Windows下TCP客户端必须先调用WSAStartup()初始化Winsock,否则socket()返回INVALID_SOCKET;需配对调用WSACleanup(),跨平台需#ifdef _WIN32;connect()失败需查具体错误码;send()/recv()需循环处理以确保数据完整收发。
Windows 下用
建 TCP 客户端,第一步必须调
不初始化 Winsock,直接调
会返回
,
返回
。这不是函数写错了,是 Windows 的强制要求。
实操建议:
必须在任何 socket 函数前调用,且只调一次;参数用
(即 Winsock 2.2),兼容性最好
程序退出前必须配对调用
,否则资源泄漏(尤其调试时反复启停容易触发
失败)
Linux/
mac
OS 不需要这一步,所以跨平台代码得加
分支
connect() 失败常见原因和检查顺序
返回 -1 并不总意味着网络不通,得看
(Windows)或
(Linux)具体值:
(10061):服务端没起来,或监听地址/端口不对(比如绑了
却从外网连)
(10060):
路由
可达但目标主机没响应——可能是
防火墙
丢包、服务端进程崩溃、或监听 socket 没
(10049):客户端 bind 时用了非法地址(如已关闭的网卡 IP),或端口被占用
Linux 下还常遇到
(非阻塞模式下),别当成错误,要配合
或
等待就绪
send()/recv() 不保证一次传完所有数据
TCP 是
字节
流协议,
只保证把数据交给内核缓冲区,不保证发到对端;
同样可能只收一部分。硬写
就认为发完了,大概率出 bug。
立即学习
“
C++免费学习笔记(深入)
”;
Trae win
Trae Windows 官方版本现已全面支持 Win10 和 Win11 系统(64位)。国内开发者可直接访问 Trae 中文官网(trae.cn 或 trae.com.cn),一键下载官方正版 .exe 安装包,享受国内直连的高速稳定体验。安装过程极其简便,双击即可运行,并支持一键无缝导入 VS Code 或 Cursor 的原有主题、快捷键及插件配置。登录支持手机号、微信或稀土掘金账号。内置免费的豆包与 DeepSeek 等顶级大模型,让你开箱即用,轻松开启高效的 AI 智能编程之旅。
下载
实操建议:
循环调用
直到
全部返回(检查返回值是否为正,负值需查错误)
接收端不能假设一次
就拿到完整报文——必须自己定义协议边界(比如头部 4 字节长度字段 + 后续内容)
避免用
直接接
返回的原始字节,二进制数据里可能含
,导致截断
close() / closesocket() 后立即重启客户端可能失败
主动关闭连接后,本地端口会进入
状态(默认约 2 分钟)。如果马上用相同端口重连,
或
可能报
。
解决办法有限且有代价:
服务端设置
(推荐):
客户端一般不设
,因为端口由系统自动分配,除非你显式
固定端口
强行缩短
时间(改系统注册表或 sysctl)风险高,不建议
真正该关注的是:别让客户端频繁短连接——长连接复用更可靠,也避开这个坑。
socket()WSAStartup()socket()INVALID_SOCKETWSAGetLastError()WSANOTINITIALISEDWSAStartup()MAKEWORD(2, 2)WSACleanup()WSAStartup#ifdef _WIN32connect()WSAGetLastError()errnoWSAECONNREFUSED127.0.0.1WSAETIMEDOUTlisten()WSAEADDRNOTAVAILEINPROGRESSselect()poll()send()recv()send(buf, len)send()lenrecv()std::stringrecv()\0int send_all(SOCKET sock, const char* buf, int len) {
int sent = 0;
while (sent < len) {
int n = send(sock, buf + sent, len - sent, 0);
if (n <= 0) return -1; // 错误或连接关闭
sent += n;
}
return sent;
}TIME_WAITbind()connect()WSAEADDRINUSESO_REUSEADDRsetsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))SO_REUSEADDRbind()TIME_WAIT