SOCKET错误

本文详细解析了在网络编程中遇到的10053错误,解释了其产生的原因及如何避免。通过分析客户端和服务端代码示例,阐述了在不同情况下的错误处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贴2段能稳定重现10053的代码,下面是客户端:

[cpp]  view plain  copy
  1. WORD    VersionRequested;  
  2. WSADATA WsaData;  
  3.   
  4. VersionRequested = MAKEWORD(2, 2);  
  5.   
  6. if (WSAStartup(VersionRequested, &WsaData))  
  7.     return -1;  
  8.   
  9. SOCKET SocketServer  = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  10. SOCKADDR_IN AddrServer;  
  11. AddrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  12. AddrServer.sin_port             = htons(9999);  
  13. AddrServer.sin_family           = AF_INET;  
  14.   
  15. // 连接服务器  
  16. if (0 != connect(SocketServer, (SOCKADDR *)&AddrServer, sizeof(SOCKADDR)))  
  17. {  
  18.     closesocket(SocketServer);  
  19.     return false;  
  20. }  
  21.   
  22. int err = 0;  
  23. char temp[] = "hello, server";  
  24. int rs = send(SocketServer, temp, sizeof(temp) + 1, 0);  
  25.   
  26. char buff[1024] = {0};  
  27. rs = recv(SocketServer, buff, sizeof(buff), 0);  
  28.   
  29.        // 下面这2句代码如果注释掉,后面的recv就能正解的返回0。如果不注释掉,recv就会返回-1,  
  30.         // 并得到10053这个错误  
  31. rs = send(SocketServer, temp, sizeof(temp) + 1, 0);  
  32. err = WSAGetLastError();  
  33.   
  34. rs = recv(SocketServer, buff, sizeof(buff), 0);  
  35. err = WSAGetLastError();  
  36.   
  37. system("pause");  
  38. return 0;  
这个是服务器的:
[cpp]  view plain  copy
  1. WORD    VersionRequested;  
  2. WSADATA WsaData;  
  3.   
  4. VersionRequested = MAKEWORD(2, 2);  
  5.   
  6. if (WSAStartup(VersionRequested, &WsaData))  
  7. {  
  8.     printf("加载socket库失败!\n");  
  9.     return -1;  
  10. }  
  11.   
  12. // 监听来自浏览器的请求  
  13. SOCKET SockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  14. SOCKADDR_IN AddrClient;  
  15. AddrClient.sin_family      = AF_INET;  
  16. AddrClient.sin_addr.s_addr = INADDR_ANY;  
  17. AddrClient.sin_port        = htons(9999);  
  18.   
  19. if (SockServer == INVALID_SOCKET)  
  20. {  
  21.     printf("socket初始化失败!\n");  
  22.     closesocket(SockServer);  
  23.     WSACleanup();  
  24.     return -1;  
  25. }  
  26.   
  27. if (bind(SockServer, (sockaddr*)&AddrClient, sizeof(AddrClient)) != 0)  
  28. {  
  29.     printf("socket绑定失败!\n");  
  30.     closesocket(SockServer);  
  31.     WSACleanup();  
  32.     return -1;  
  33. }  
  34.   
  35. if (listen(SockServer, 10) != 0)  
  36. {  
  37.     printf("socket监听失败!\n");  
  38.     closesocket(SockServer);  
  39.     WSACleanup();  
  40.     return -1;  
  41. }  
  42.   
  43. while (1)  
  44. {  
  45.     SOCKET NewSocket = accept(SockServer, NULL, NULL);  
  46.     if (INVALID_SOCKET == NewSocket)  
  47.     {  
  48.         closesocket(NewSocket);  
  49.         continue;  
  50.     }  
  51.     else  
  52.     {  
  53.         struct linger so_linger;  
  54.         so_linger.l_onoff  = 1;  
  55.         so_linger.l_linger = 30;  
  56.         setsockopt(NewSocket ,SOL_SOCKET, SO_LINGER, (const char*)&so_linger, sizeof(so_linger));   
  57.     }  
  58.   
  59.     char buff[1024];  
  60.     int rs = recv(NewSocket, buff, sizeof(buff), 0);  
  61.   
  62.     char temp[] = "hello, client";  
  63.     rs = send(NewSocket, temp, sizeof(temp) + 1, 0);  
  64.   
  65.     closesocket(NewSocket);  
  66. }  
10053里说的software在我的例子中指的就是那个send函数吗,是send函数执行的时候,发现对方的套接字已经关闭了,所以它把己方的套接字也关掉了吗,然后导致后续的recv报错10053?



出现10053的原因是因为在你执行这次send的时候对端已经执行过closesocket了,而发送的数据还是被成功的推入了发送缓冲区中,因此返回了0,此时你可能还没得到FIN消息,而紧接着recv这边就得到了对端关闭socket的FIN消息,因此此时需要放弃发送缓冲中的数据,异常终止连接,所以得到了
10053错误:您的主机中的软件中止了一个已建立的连接。 

而为什么又能得到10054的错误号,原因应该在于你设置了SO_LINGER了,一但设置了它,则有一个等待时间,在该等待时间内可以处理发送缓冲区的数据,一但超时或者发送缓冲都被发送完并被确认,则服务端有可能发送RST消息而不是FIN,此时就应该得到重置错误,也就是10054。

不同的系统对SO_LINGER的实现方式不一样,得到的结果也不一样,不知道按我这样解释是否对你有帮助。如果我有理解错误,欢迎大家指正。











socket error- Software caused connection abort. Error code : 10053


Action.c(16): Error : socket0 - Software caused connection abort. Error code : 10053.



10053这个错误,产生于socket通讯过程中,通常是这么回事:
正常的C/S通讯过程是:

Server Listen; 


Client Connect;


Server Accept; 


Client Send; 


Server Recv; 


Client Close; 


Server Close


如果Client端不主动关闭连接而直接退出,则Server端的服务线程会引发一个10053错误(这种错误通常影响不太大), 而如果通讯过程中Server首先主动关闭连接,则Client端也会引发一个10053错误

网络不好的时候的情况通常是指后者,Client以为Server关了(实际是网络断了), 所以就大叫10053

在使用 socket 编程时,错误码(`errno`)是诊断问题的关键依据。不同的错误码代表了不同类型的故障,以下是常见 socket 错误的原因及其解决方法。 ### 常见 socket 错误原因及解决方案 #### 1. **errno = 104: Connection reset by peer** 此错误表示远程主机关闭了连接,通常是由于对端异常终止或网络中断导致的。例如,在非阻塞模式下进行 `connect()` 或 `write()` 操作时遇到该错误,可能是因为没有正确处理 `SIGPIPE` 信号。 - **原因**: - 对端关闭连接后仍尝试写入数据。 - 网络连接中断。 - 服务端异常退出。 - **解决方法**: - 在程序中添加对 `SIGPIPE` 信号的处理,可以选择忽略该信号或自定义信号处理函数。 - 使用 `signal(SIGPIPE, SIG_IGN)` 忽略信号以避免程序意外退出。 - 检查网络稳定性及对端服务是否正常运行。 #### 2. **errno = 118: Socket operation on non-socket** 此错误通常出现在尝试对无效的文件描述符执行 socket 操作时。例如在 ESP32 开发中设置 `SO_REUSEADDR` 后出现该错误,可能是套接字未正确初始化或配置顺序不当。 - **原因**: - 文件描述符不是有效的 socket。 - 套接字未成功创建即调用 `setsockopt()`。 - **解决方法**: - 确保在调用任何 socket API 前,先通过 `socket()` 成功创建 socket 描述符。 - 避免重复使用已关闭的 socket。 - 正确设置 socket 选项顺序,确保 `bind()` 和 `listen()` 等操作按预期执行。 #### 3. **errno = 111: Connection refused** 当尝试连接到一个未监听的端口或服务未启动时会触发该错误。 - **原因**: - 目标主机未运行对应服务。 - 防火墙阻止了连接请求。 - 地址或端口配置错误。 - **解决方法**: - 确认目标服务是否正在运行。 - 检查本地和远程防火墙设置。 - 核实 IP 地址和端口号是否正确。 #### 4. **errno = 110: Connection timed out** 连接超时通常发生在长时间未收到响应或网络延迟过高时。 - **原因**: - 网络延迟过大。 - 服务器无响应。 - 超时设置不合理。 - **解决方法**: - 增加连接超时时间。 - 检查网络连接质量。 - 实现重试机制以应对短暂网络波动。 #### 5. **errno = 4048 / ERR_SOCKET_TIMEOUT (npm 报错)** 在 Node.js 中使用 npm 安装包时,若出现 `ERR_SOCKET_TIMEOUT`,则可能是代理设置或网络连接问题。 - **原因**: - 代理配置不正确。 - 网络不稳定或 DNS 解析失败。 - 远程服务器无响应。 - **解决方法**: - 检查并更新 npm 的代理配置:`npm config set proxy http://your-proxy-url:port`。 - 更换 DNS 或检查网络连通性。 - 使用 `npm config set timeout 300000` 提高超时限制。 --- ### 示例代码:忽略 SIGPIPE 信号 ```c #include <signal.h> // 忽略 SIGPIPE 信号 signal(SIGPIPE, SIG_IGN); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值