You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言异步端口扫描开发:创建大量socket报EMFILE错误咨询

根因说明

你遇到的EMFILE(错误码24,Too many open files)和socket接口本身的能力无关,是Linux系统默认对单进程可持有的文件描述符(FD)做了数量限制。Linux下所有socket都会被抽象为文件描述符,多数发行版默认单进程FD软上限为1024,你预创建5000个socket的逻辑直接触发了这个限制,因此报错。

如何无错误创建大量socket

不需要修改内核源码,先调整系统FD限制即可:

  • 临时测试可在启动程序前执行命令ulimit -n 65535,将当前shell会话下的单进程FD上限调整为65535,再运行你的示例代码就不会在创建5000个socket时报错。需要永久生效的话,修改/etc/security/limits.conf,对应用户下配置nofile的软、硬限制,重新登录会话后生效。
  • 代码层可在初始化阶段调用setrlimit(RLIMIT_NOFILE, &rlim)接口,主动将进程的FD上限设置为业务需要的值,避免运行环境默认配置过低触发错误。

注意:即便调高了FD上限,也不建议采用预创建全量socket的实现方式。每个空闲socket都会占用内核态内存,扫描规模扩大后会造成严重的资源浪费。

是否需要调整技术方案

必须调整,你当前预创建全量socket的实现效率极低,完全无法支撑大规模端口扫描的需求,按实现难度从低到高可选择以下方案:

  • 中小规模扫描(单IP全端口、C段探测):基于epoll实现事件驱动的连接池,不要预创建socket。维护一个固定长度的活跃连接队列(长度可设为1000~2000,远低于FD上限),当队列中有连接完成(成功/失败/超时)被回收时,再新建socket补充队列,全程FD占用稳定,资源开销极低。同时给socket设置SO_REUSEADDR、TCP_NODELAY参数,将连接超时压缩到1s以内,可进一步提升扫描效率。
  • 大规模扫描(十万级以上IP、每秒万级以上探测速率):上述内核态socket方案的性能会遇到瓶颈,需要更底层的实现。
是否需要参考masscan绕过内核协议栈

根据你的扫描规模决定,不要盲目上复杂方案:

  • 如果扫描范围是内网、少量公网IP段,完全不需要。绕过内核协议栈的开发成本极高,需要自行处理TCP三次握手、ARP解析、路由选路、IP分片等逻辑,问题排查难度大,epoll方案完全可以满足需求。
  • 如果需要做高速大范围扫描(比如每秒发送10万+探测包、跑满千兆/万兆网卡带宽),就必须参考masscan、zmap的实现思路:通过原始套接字(raw socket)或者PF_RING、DPDK等用户态网卡框架,直接在用户态构造TCP SYN探测包发送,自行处理收到的SYN/ACK、RST响应,完全跳过内核TCP协议栈的处理流程。这种方案只需要1~2个原始套接字就能工作,根本不会触发FD数量限制,扫描速率比内核态socket方案高两个数量级以上。

注意:高速构造发送探测包极易触发目标网络、运营商的限流和封禁,实际使用时请控制扫描速率,遵守网络安全相关法律法规。

内容的提问来源于stack exchange,提问作者Rainbow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 19:06:40