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

TCP Socket无法多次连接至服务端问题排查求助

问题排查:TCP连接多次创建后阻塞,服务端仅接收首个连接数据

核心问题分析

1. Socket资源泄漏导致本地端口耗尽

你的代码在每次创建Socket并发送数据后,没有调用close(sock)释放资源。即使注释说明“假设每个Socket是长连接”,但在循环创建短连接的场景下,未关闭的Socket会持续占用系统文件描述符和本地端口。

Linux系统中本地可用端口数量有限(默认范围32768-60999),且TCP连接关闭后会进入TIME_WAIT状态(默认持续约1-2分钟),期间端口无法被复用。当可用端口耗尽后,新的connect调用会因无法分配本地端口而阻塞。

2. 服务端连接处理逻辑限制

  • 普通nc 127.0.0.1 1234启动的netcat服务端仅处理第一个连接,连接关闭后才会接受下一个请求。如果客户端同时创建多个连接,服务端的全连接队列(ACCEPT队列)会被占满,后续客户端的connect请求会被阻塞。
  • 基础Boost.Asio服务端如果只实现了单次accept逻辑,同样会出现只处理第一个连接、后续请求排队阻塞的问题。

修复方案

方案1:正确释放Socket资源

在发送数据后,及时关闭不再使用的Socket。如果是长连接场景,需确保连接不再活跃时调用close释放资源。修改代码如下:

// Send data
std::string txt = "hello world" + std::to_string(i) + "\n";
ssize_t sent = send(sock, txt.data(), txt.size(), 0);
if (sent < 0) {
    perror("send");
    close(sock);
    return 1;
}

// 释放Socket资源
close(sock);

方案2:调整服务端支持多连接

  • netcat:添加-k参数,让服务端在连接关闭后持续监听新连接:
    nc -lk 127.0.0.1 1234
    
  • Boost.Asio服务端:实现循环accept逻辑,每次接受新连接后通过异步回调或线程池处理,避免阻塞主监听流程。

验证方法

使用以下命令查看连接状态,确认是否存在大量TIME_WAIT或未关闭的Socket:

netstat -antp | grep 1234

内容的提问来源于stack exchange,提问作者Jean-Michaël Celerier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:45:21