Skip to content

Commit 0604a34

Browse files
committed
feat: 添加教育网默认强制解析ipv6以实现免流。同时支持手动指定ipv6和ipv4。
1 parent a8caf62 commit 0604a34

2 files changed

Lines changed: 65 additions & 0 deletions

File tree

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ pip install requests tqdm
9191
python hf_downloader.py bert-base-uncased
9292
python hf_downloader.py openai/whisper-large-v3 --type model
9393
python hf_downloader.py bigcode/starcoder --revision main --workers 8
94+
95+
# 网络优化选项
96+
python hf_downloader.py bert-base-uncased -4 # 强制使用 IPv4
97+
python hf_downloader.py bert-base-uncased -6 # 强制使用 IPv6
98+
# 注:脚本会自动检测教育网环境(CERNET),如检测到则默认开启 IPv6 优化,无需手动指定
9499
```
95100

96101
## 🔧 工作原理

src/scripts/hf_downloader.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import argparse
1616
import os
1717
import sys
18+
import socket
1819
import json
1920
import hashlib
2021
import threading
@@ -40,6 +41,42 @@
4041
DEFAULT_WORKERS = 4 # 默认并行下载数
4142

4243

44+
def check_cernet() -> bool:
45+
"""检查是否为教育网环境"""
46+
try:
47+
#设置较短超时,避免阻塞
48+
resp = requests.get("http://ip-api.com/json/?fields=isp,org", timeout=3)
49+
if resp.ok:
50+
data = resp.json()
51+
isp = data.get("isp", "").lower()
52+
org = data.get("org", "").lower()
53+
# 常见的教育网标识
54+
cernet_keywords = ["cernet", "education", "university"]
55+
if any(k in isp for k in cernet_keywords) or any(k in org for k in cernet_keywords):
56+
return True
57+
except:
58+
pass
59+
return False
60+
61+
62+
def configure_dns(force_ipv4: bool = False, force_ipv6: bool = False):
63+
"""配置 DNS 解析优先级"""
64+
if not (force_ipv4 or force_ipv6):
65+
return
66+
67+
original_getaddrinfo = socket.getaddrinfo
68+
69+
def patched_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
70+
# 如果强制指定了协议版本,则覆盖 family 参数
71+
if force_ipv4:
72+
family = socket.AF_INET
73+
elif force_ipv6:
74+
family = socket.AF_INET6
75+
return original_getaddrinfo(host, port, family, type, proto, flags)
76+
77+
socket.getaddrinfo = patched_getaddrinfo
78+
79+
4380
@dataclass
4481
class FileInfo:
4582
"""文件信息"""
@@ -318,8 +355,31 @@ def main():
318355
parser.add_argument("--token", help="Hugging Face Token (也可设置 HF_TOKEN 环境变量)")
319356
parser.add_argument("--list-only", "-l", action="store_true",
320357
help="仅列出文件,不下载")
358+
parser.add_argument("--ipv4", "-4", action="store_true", help="强制使用 IPv4")
359+
parser.add_argument("--ipv6", "-6", action="store_true", help="强制使用 IPv6")
321360

322361
args = parser.parse_args()
362+
363+
# 处理 IP 协议选择
364+
if args.ipv4 and args.ipv6:
365+
print("❌ 错误: 不能同时指定 -4 和 -6")
366+
sys.exit(1)
367+
368+
use_ipv6 = args.ipv6
369+
use_ipv4 = args.ipv4
370+
371+
# 如果未指定,自动检测是否为教育网
372+
if not (use_ipv6 or use_ipv4):
373+
if check_cernet():
374+
print("🎓 检测到教育网环境,自动启用 IPv6 优化")
375+
use_ipv6 = True
376+
377+
if use_ipv6:
378+
print("🌐 已启用强制 IPv6 解析")
379+
configure_dns(force_ipv6=True)
380+
elif use_ipv4:
381+
print("🌐 已启用强制 IPv4 解析")
382+
configure_dns(force_ipv4=True)
323383

324384
print(f"""
325385
╔══════════════════════════════════════════════════════════════╗

0 commit comments

Comments
 (0)