{"id":43992961,"url":"https://github.com/cnbatch/udphop","last_synced_at":"2026-02-07T11:05:48.770Z","repository":{"id":83600985,"uuid":"570946142","full_name":"cnbatch/udphop","owner":"cnbatch","description":"专用于UDP的端口跳跃及IP地址跳跃工具。A tool of UDP's Port Hopping \u0026 IP Address Hopping","archived":false,"fork":false,"pushed_at":"2025-11-29T08:26:28.000Z","size":468,"stargazers_count":134,"open_issues_count":3,"forks_count":13,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-01T09:52:03.432Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cnbatch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-11-26T16:41:16.000Z","updated_at":"2025-11-29T08:21:13.000Z","dependencies_parsed_at":"2023-11-11T10:25:42.677Z","dependency_job_id":"74658f08-b862-4d21-a374-213281d5143c","html_url":"https://github.com/cnbatch/udphop","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/cnbatch/udphop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbatch%2Fudphop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbatch%2Fudphop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbatch%2Fudphop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbatch%2Fudphop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cnbatch","download_url":"https://codeload.github.com/cnbatch/udphop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cnbatch%2Fudphop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29193090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-07T11:05:48.711Z","updated_at":"2026-02-07T11:05:48.763Z","avatar_url":"https://github.com/cnbatch.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UDP Hop\n\n[Click Here for English Version](README_EN.md)\n\n## 简单介绍\n但凡使用过三大运营商的家用宽带，并且需要家宽互联，那么几乎都会体验到 UDP 被限速的情况。\n\n为了解决UDP限速，目前比较常用的做法是使用 udp2raw 之类的工具“变成” TCP 流量。可惜的是， udp2raw 服务端版只支持 Linux。类似 udp2raw 的还有 Phantun。\n\n那么能不能继续用 UDP 规避限速？这样做灵活性就可以高一点了。也许可以，有人提到过，UDP 被限速后只要重新连接，速度就会重新恢复。\n\n既然如此，那就可以基于这个思路造一个新工具——就叫做 UDP Hop。**每隔一段时间，UDP Hop客户端就会自动重新建立连接，并把传输链路转移到新连接上继续传送。**\n\n为了方便家宽 Full Cone NAT 用户使用，UDP Hop以服务端基本模式运行的时候可以利用 STUN 打洞，同时支持 IPv4 与 IPv6。\n\n### 细节介绍\n不同于 TCP 伪装工具，UDP Hop 全程保持 UDP，并且会在内部为每一个 UDP 连接（“源IP:源端口”的二元组）分配 Session ID，以此区分多个 UDP 连接。超时时间为 180 秒，换句话说，单个 Session 超过 3 分钟无流量就会自动清除。\n\n实际使用时请根据设备性能适当调整跳换端口的频率，以免对自己的网关设备造成较大的 NAT 压力从而影响网络性能。若条件允许，建议运行在软路由上。如果软路由本身就是网关的话，这样做就可以免除 NAT 负担。\n\n#### 关联项目\n如果想同时转发TCP流量，可以试试 [KCP Tube](https://github.com/cnbatch/kcptube)\n\n\n## 用法\n\n**注意**，客户端的时间与服务端的时间务必同步，时间相差不能大于 255 秒。\n\n### 基本用法\n`udphop config.conf`\n\n客户端模式示例：\n```\nmode=client\nlisten_port=59000\ndestination_port=3000\ndestination_address=123.45.67.89\ndport_refresh=3600\nencryption_password=qwerty1234\nencryption_algorithm=AES-GCM\n```\n\n服务端模式示例：\n```\nmode=server\nlisten_port=3000\ndestination_port=59000\ndestination_address=::1\nencryption_password=qwerty1234\nencryption_algorithm=AES-GCM\nstun_server=stun.qq.com\nlog_path=./\n```\n\n备注：客户端模式的 `listen_port` 不一定非要等于服务端模式的 `destination_port`，两边的端口可以不一致。\n\n如果要指定侦听的网卡，那就指定该网卡的 IP 地址，加一行即可\n```\nlisten_on=192.168.1.1\n```\n\n如果想要侦听多个端口、多个网卡，那就分开多个配置文件\n\n```\nudphop config1.conf config2.conf\n```\n\n#### 验证配置文件\n使用 ``--check-config`` 选项即可验证配置文件是否正确：\n```\nkcptube --check-config config1.conf\n```\n或\n```\nkcptube config1.conf --check-config\n```\n\n### 更灵活用法——服务端模式动态端口\n\n客户端模式示例：\n```\nmode=client\nlisten_port=6000\ndestination_port=3000-4000\ndestination_address=123.45.67.89\ndport_refresh=3600\nencryption_password=qwerty1234\nencryption_algorithm=AES-GCM\n```\n\n服务端模式示例：\n```\nmode=server\nlisten_port=3000-4000\ndestination_port=6000\ndestination_address=::1\nencryption_password=qwerty1234\nencryption_algorithm=AES-GCM\n```\n\n### 参数介绍\n\n|  名称                | 可设置值            | 必填 |备注|\n|  ----                | ----               | ---- | ---- |\n| mode                 | client\u003cbr /\u003eserver\u003cbr /\u003erelay   |是    |客户端\u003cbr /\u003e服务端\u003cbr /\u003e中继模式|\n| listen_on            | 域名或 IP 地址      |否    |只能填写域名或 IP 地址。多个地址请用逗号分隔|\n| listen_port          | 1 - 65535          |是    |以服务端运行时可以指定端口范围|\n| destination_port     | 1 - 65535          |是    |以客户端运行时可以指定端口范围|\n| destination_address  | IP地址、域名        |是    |填入 IPv6 地址时不需要中括号。多个地址请用逗号分隔|\n| destination_dnstxt   | 域名               |否    |仅接受单个地址，仅限客户端使用。从DNS TXT记录当中获取IP地址及端口号。使用该参数时，不必填写destination_address及destination_port|\n| dport_refresh        | 20 - 65535         |否    |单位“秒”。预设值 60 秒，小于20秒按20秒算，大于65535时按65536秒算|\n| encryption_algorithm | XOR\u003cbr\u003eAES-GCM\u003cbr\u003eAES-OCB\u003cbr\u003echacha20\u003cbr\u003exchacha20\u003cbr\u003enone |否    |单纯异或运算\u003cbr\u003eAES-256-GCM-AEAD\u003cbr\u003eAES-256-OCB-AEAD\u003cbr\u003eChaCha20-Poly1305\u003cbr\u003eXChaCha20-Poly1305\u003cbr\u003e不加密 |\n| encryption_password  | 任意字符            |视情况|设置了 encryption_algorithm 使用加密时必填，none与XOR除外|\n| timeout              | 0 - 65535          |否    |单位“秒”。预设值为 1800，设为 0 则使用预设值\u003cbr\u003e该选项表示的是，UDP 应用程序 ↔ udphop 之间的超时设置 |\n| keep_alive           | 0 - 65535          |否    |预设值为 0，等于停用 Keep Alive |\n| stun_server          | STUN 服务器地址     |否    |listen_port 为端口范围模式时不可使用|\n| update_ipv4          | 可执行文件的路径     |否    |用于保存stun获得的信息，请往后阅读|\n| update_ipv6          | 可执行文件的路径     |否    |用于保存stun获得的信息，请往后阅读|\n| log_path             | 存放 Log 的目录     |否    |不能指向文件本身|\n| ipv4_only | yes\u003cbr\u003etrue\u003cbr\u003e1\u003cbr\u003eno\u003cbr\u003efalse\u003cbr\u003e0 |否|纯 IPv4 模式|\n| ipv6_only | yes\u003cbr\u003etrue\u003cbr\u003e1\u003cbr\u003eno\u003cbr\u003efalse\u003cbr\u003e0 |否|纯 IPv6 模式|\n| fec                  | uint8:uint8        |否    |格式为 `fec=D:R`，例如可以填入 `fec=20:3`。\u003cbr\u003e注意：D + R 的总数最大值为 255，不能超过这个数。\u003cbr\u003e冒号两侧任意一个值为 0 表示不使用该选项。两端的设置必须相同。|\n| \\[listener\\] | N/A |是\u003cbr\u003e(仅限中继模式)|中继模式的标签，用于指定监听模式的 UDPHop 设置\u003cbr\u003e该标签表示与客户端交互数据|\n| \\[forwarder\\] | N/A  |是\u003cbr\u003e(仅限中继模式)|中继模式的标签，用于指定转运模式的 UDPHop 设置\u003cbr\u003e该标签表示与服务端交互数据|\n\n#### 前向纠错 (FEC, Forward Error Correction)\nFEC 格式为 `fec=D:R`，其中 D 表示原始数据量，R 表示冗余数据量。D + R 的总数最大值为 255，不能超过这个数。\n\n例如可以填入 `fec=20:4`，表示每发送 20 个数据包，就生成并发送 4 个冗余包。\n\n**提醒**：不建议 AEAD 加密模式的 OpenVPN 使用这项功能，因为此时的 OpenVPN 对于乱序数据包的容忍度极差，而 UDPHop 并不负责重新排序数据包，即使是 FEC 恢复的数据同样如此。\n\n#### 中继模式\n请参看[中继模式使用说明](docs/relay_mode_zh-hans.md).\n\n### Log 文件\n在首次获取打洞后的 IP 地址与端口后，以及打洞的 IP 地址与端口发生变化后，会向 Log 目录创建 ip_address.txt 文件（若存在就覆盖），将 IP 地址与端口写进去。\n\n获取到的打洞地址会同时显示在控制台当中。\n\n`log_path=` 必须指向目录，不能指向文件本身。\n\n如果不需要写入 Log 文件，那就删除 `log_path` 这一行。\n\n### STUN 选项\n\n这三个参数仅限服务器模式、中继模式时使用：\n- stun_server\n- update_ipv4\n- update_ipv6\n\n设置好 `update_ipv4` 或 `update_ipv4` 之后，程序会运行对应程序，把 stun 获取到的IP地址及端口传递过去。\n\n例如，设置了\n```\nupdate_ipv4=/home/test/update_to_dnsv4\nupdate_ipv6=/home/test/update_to_dnsv6\n```\n\n从 stun 获取到的地址、端口号分别是130.131.132.133、23456，那么运行的文件及传递的参数是：\n\n```\n/home/test/update_to_dnsv4 130.131.132.133:23456\n```\n如果获取到的地址、端口号分别是2409:ABCD:FEDC:3210::1、23456，那么运行的文件及传递的参数是：\n```\n/home/test/update_to_dnsv6 [2409:ABCD:FEDC:3210::1]:23456\n```\n\n### STUN Servers\n\n从[NatTypeTeste](https://github.com/HMBSbige/NatTypeTester)找到的普通 STUN 服务器：\n- stun.syncthing.net\n- stun.qq.com\n- stun.miwifi.com\n- stun.bige0.com\n- stun.stunprotocol.org\n\n从[Natter](https://github.com/MikeWang000000/Natter)找到的STUN 服务器：\n\n- fwa.lifesizecloud.com\n- stun.isp.net.au\n- stun.freeswitch.org\n- stun.voip.blackberry.com\n- stun.nextcloud.com\n- stun.stunprotocol.org\n- stun.sipnet.com\n- stun.radiojar.com\n- stun.sonetel.com\n- stun.voipgate.com\n\n其它 STUN 服务器：[public-stun-list.txt](https://gist.github.com/mondain/b0ec1cf5f60ae726202e)\n\n### DNS TXT\n从TXT类型的域名当中获取一段文字内容，该文字内容包含**单个**主机地址及端口号。\n\n文字内容的格式示例（IPv4地址）：\n```\n192.168.0.1:65001\n```\n\n文字内容的格式示例（IPv6地址）：\n```\n[::1]:65001\n```\n\n文字内容的格式示例（域名）：\n```\nexample.com:65001\n```\n\n无效格式示例：\n```\n192.168.0.1:65001,[::1]:65001\n```\n不可以同时提供多个地址\n\n```\n[192.168.0.1]:65001\n```\nIPv4不需要使用中括号\n\n```\n2409:abcd:dcba::1:65001\n```\nIPv6必须使用中括号\n\n---\n\n## 预编译二进制\n为了方便使用，目前已经提供了多个平台的二进制可执行文件：\n- Windows\n- FreeBSD\n- Linux\n\n预编译的二进制文件全部都是静态编译。Linux 版本基本上都是静态编译，但 libc 除外，因此准备了两个版本，一个用于 glibc (2.36)，另一个用于 musl。\n\n### Docker 镜像\n\n对于 Linux 环境，另有提供 Docker 镜像（目前仅限 x64），下载 udphop_docker_image.zip 并解压，再使用 `docker load -i udphop_docker.tar` 导入。\n\n导入后，使用方式为：\n```\ndocker run -v /path/to/config_file.conf:/config_file.conf udphop config_file.conf\n```\n\n例如：\n```\ndocker run -v /home/someone/config1.conf:/config1.conf udphop config1.conf\n```\n\n---\n\n## 建立服务\n### FreeBSD\n\nFreeBSD 用户可将下载好的二进制文件复制到 `/usr/local/bin/`，然后运行命令\n```\nchmod +x /usr/local/bin/udphop\n```\n\n本项目的 `service` 目录已经准备好相应服务文件。\n\n1. 找到 udphop 文件，复制到 `/usr/local/etc/rc.d/`\n2. 运行命令 `chmod +x /usr/local/etc/rc.d/udphop`\n3. 把配置文件复制到 `/usr/local/etc/udphop/`\n    - 记得把配置文件命名为 `config.conf`\n        - 完整的路径名：`/usr/local/etc/udphop/config.conf`\n4. 在 `/etc/rc.conf` 加一行 `udphop_enable=\"YES\"`\n\n最后，运行 `service udphop start` 即可启动服务\n\n---\n\n## 编译\n编译器须支持 C++20\n\n依赖库：\n\n- [asio](https://github.com/chriskohlhoff/asio) ≥ 1.18.2\n- [botan3](https://github.com/randombit/botan)\n\n### Windows\n请事先使用 vcpkg 安装依赖包 `asio` 及 botan3，一句命令即可：\n\n```\nvcpkg install asio:x64-windows asio:x64-windows-static botan:x64-windows botan:x64-windows-static\nvcpkg install botan:x64-windows botan:x64-windows-static botan:x64-windows botan:x64-windows-static\n```\n（如果需要 ARM 或者 32 位 x86 版本，请自行调整选项）\n\n然后用 Visual Studio 打开 `sln\\udphop.sln` 自行编译\n\n### FreeBSD\n同样，请先安装依赖项 asio 以及 botan3，另外还需要 cmake，用系统自带 pkg 即可安装：\n\n```\npkg install asio botan3 cmake\n```\n接着在 build 目录当中构建\n```\nmkdir build\ncd build\ncmake ..\nmake\n```\n\n### NetBSD\n请使用 [pkgin](https://www.netbsd.org/docs/pkgsrc/using.html) 安装依赖项与 cmake：\n```\npkgin install asio botan3 cmake\n```\n\n由于系统内置的GCC版本较低，须额外安装新版GCC：\n\n```\npkgin install gcc13\n```\n接着在 build 目录当中构建\n```\nmkdir build\ncd build\ncmake -D CMAKE_CXX_COMPILER=/usr/pkg/gcc13/bin/c++ -D CMAKE_C_COMPILER=/usr/pkg/gcc13/bin/cc ..\nmake\n```\n\n### OpenBSD\n\nOpenBSD 请使用 `pkg_add` 安装依赖项与 cmake：\n\n```\npkg_add asio\npkg_add cmake\n```\n\n目前 botan-3 仍未被 OpenBSD 收录，须自行编译 botan-3。建议编译完成后放入 `/usr/local/include/`，完整路径为 `/usr/local/include/botan-3/`，就像FreeBSD那样。\n\n由于系统内置的Clang版本较低，须额外安装新版Clang：\n\n```\npkg_add llvm\n```\n\n请选择最新版本。\n\n接着在 build 目录当中构建：\n```\nmkdir build\ncd build\ncmake -D CMAKE_CXX_COMPILER=/usr/local/bin/clang++-19 -D CMAKE_C_COMPILER=/usr/local/bin/clang-19 ..\nmake\n```\n\n### DragonflyBSD\n\n与 FreeBSD 一样，使用 `pkg` 安装依赖项与 cmake：\n\n```\npkg install asio cmake\n```\n\n目前 botan-3 仍未被 DragonflyBSD 收录，须自行编译 botan-3。建议编译完成后放入 `/usr/local/include/`，完整路径为 `/usr/local/include/botan-3/`，就像FreeBSD那样。\n\n由于系统内置的GCC版本较低，须额外安装新版GCC：\n\n```\npkg install gcc14\n```\n\n接着在 build 目录当中构建\n```\nmkdir build\ncd build\ncmake -D CMAKE_CXX_COMPILER=/usr/local/bin/c++14 -D CMAKE_C_COMPILER=/usr/local/bin/gcc14 -D CMAKE_INSTALL_RPATH=/usr/local/lib/gcc14 -D CMAKE_BUILD_WITH_INSTALL_RPATH=ON ..\nmake\n```\n\n### Linux\n步骤与 FreeBSD 类似，请用发行版自带的包管理器安装 asio 与 botan3 以及 cmake。\n\n#### Alpine\n````\napk add asio botan3-libs cmake\n````\n接着在 build 目录当中构建\n```\nmkdir build\ncd build\ncmake ..\nmake\n```\n\n#### 静态编译注意事项\n有两种做法\n\n- **做法1**\n\n    按照正常流程编译好，删除刚刚生成的 udphop 二进制文件，并运行命令\n    ```\n    make VERBOSE=1\n    ```\n    再从输出的内容提取出最后一条 C++ 链接命令，把中间的 `-lbotan-3` 改成 libbotan-3.a 的**完整路径**，例如 `/usr/lib/x86_64-linux-gnu/libbotan-3.a`。\n\n\n- **做法2**\n\n    打开 src/CMakeLists.txt，把 `target_link_libraries(${PROJECT_NAME} PRIVATE botan-3)` 改成 `target_link_libraries(${PROJECT_NAME} PRIVATE botan-3 -static)`\n\n    然后即可正常编译。注意，如果系统使用 glibc 的话，这样会连同 glibc 一并静态编译，从而会跳出有关 getaddrinfo 的警告。\n\n### macOS\n我没苹果电脑，所有步骤请自行解决。\n\n---\n\n## 对 UDP 传输性能的改善\n增加接收缓存可以改善 UDP 传输性能\n### FreeBSD\n可以使用命令 `sysctl kern.ipc.maxsockbuf` 查看缓存大小。如果需要调整，请运行命令（数字改为想要的数值）：\n```\nsysctl -w kern.ipc.maxsockbuf=33554434\n```\n或者在 `/etc/sysctl.conf` 写入 \n```\nkern.ipc.maxsockbuf=33554434\n```\n### NetBSD \u0026 OpenBSD\n可以使用命令 `sysctl net.inet.udp.recvspace` 查看接收缓存大小。如果需要调整，请运行命令（数字改为想要的数值）：\n```\nsysctl -w net.inet.udp.recvspace=33554434\n```\n或者在 `/etc/sysctl.conf` 写入 \n```\nnet.inet.udp.recvspace=33554434\n```\n若有必要，可以同时调整 `net.inet.udp.sendspace` 的数值。这是发送缓存的设置。\n### Linux\n对于接收缓存，可以使用命令 `sysctl net.core.rmem_max` 及 `sysctl net.core.rmem_default` 查看接收缓存大小。\n\n如果需要调整，请运行命令（数字改为想要的数值）：\n```\nsysctl -w net.core.rmem_max=33554434\nsysctl -w net.core.rmem_default=33554434\n```\n或者在 `/etc/sysctl.conf` 写入 \n```\nnet.core.rmem_max=33554434\nnet.core.rmem_default=33554434\n```\n若有必要，可以同时调整 `net.core.wmem_max` 及 `net.core.wmem_default` 的数值。这是发送缓存的设置。\n\n## IPv4 映射 IPv6\n由于 udphop 内部使用的是 IPv6 单栈 + 开启 IPv4 映射地址（IPv4-mapped IPv6）来同时使用 IPv4 与 IPv6 网络，因此请确保 v6only 选项的值为 0。\n\n**正常情况下不需要任何额外设置，FreeBSD 与 Linux 以及 Windows 都默认允许 IPv4 地址映射到 IPv6。**\n\n如果系统不支持 IPv6，或者禁用了 IPv6，请在配置文件中设置 ipv4_only=true，这样 udphop 会退回到使用 IPv4 单栈模式。\n\n## 其它注意事项\n### MTU\n\nUDPHop 并不拆分数据包，只会在原有数据包上套个“壳”。所以对于 OpenVPN 之类的程序而言，需要修改 MTU 值的设置。\n\nUDPHop “壳”的大小为：\n\nUDPHop 数据头占用 12 字节。\n\n- 加密选项\n    - 若启用加密，会增加 48 字节\n    - 若不启用加密，则只增加 2 字节用于校验和\n\n若启用 FEC，就再占用 5 字节。\n\n### NetBSD\n使用命令\n```\nsysctl -w net.inet6.ip6.v6only=0\n```\n设置后，单栈+映射地址模式可以侦听双栈。\n\n但由于未知的原因，无法主动连接 IPv4 映射地址。\n\n### OpenBSD\n因为 OpenBSD 彻底屏蔽了 IPv4 映射地址，所以在 OpenBSD 平台使用双栈的话，需要将配置文件保存成两个，其中一个启用 ipv4_only=1，然后在使用 udphop 时同时载入两个配置文件。\n\n### 多种系统都遇到的 Too Many Open Files\n大多数情况下，这种提示只会在服务器端遇到，不会在客户端遇到。\n\n如果确实在客户端遇到了，请检查 `mux_tunnels` 的数值是否过高（请顺便参考“多路复用 (mux_tunnels=N)”段落）。\n#### GhostBSD\n一般情况下，绝大多数 BSD 系统都不会遇到这种事，只有 2023 年下半年更新后的 GhostBSD 才会遇到这种现象。\n\n这是因为 GhostBSD 在 `/etc/sysctl.conf` 当中加了这一行：\n```\nkern.maxfiles=100000\n```\n这一行缩减了上限，远低于原版 FreeBSD 的对应数值。\n\n解决办法很简单，删掉这一行即可。注释掉也可以。\u003cbr /\u003e\n还可以使用命令 `sysctl kern.maxfiles=300000` 临时修改上限值。\n\n#### Linux\n由于 Linux 系统的 Open Files 数量限制为 1024，所以很容易会遇到这种问题。\n\n临时解决办法：\n1. 运行命令 `ulimit -n`，查看输出的数值\n2. 如果数值确实只有 1024，请运行命令 `ulimit -n 300000`\n\n永久解决办法：\u003cbr /\u003e\n编辑 /etc/security/limits.conf，在末尾加上\n\n```\n*         hard    nofile       300000\n*         soft    nofile       300000\nroot      hard    nofile       300000\nroot      soft    nofile       300000\n```\n\n## 关于代码\n\n### 线程池\nudphop 使用的线程池来自于 [task-thread-pool](https://github.com/alugowski/task-thread-pool)，用于多连接时的并行加解密处理。\n\n### 版面\n代码写得很随意，想到哪写到哪，因此版面混乱。\n\n至于阅读者的感受嘛…… 那肯定会不爽。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnbatch%2Fudphop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcnbatch%2Fudphop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcnbatch%2Fudphop/lists"}