socket error 10053,10054究竟是怎么引起的

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

	WORD    VersionRequested;
	WSADATA WsaData;

	VersionRequested = MAKEWORD(2, 2);

	if (WSAStartup(VersionRequested, &WsaData))
		return -1;

	SOCKET SocketServer  = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN AddrServer;
	AddrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	AddrServer.sin_port             = htons(9999);
	AddrServer.sin_family           = AF_INET;

	// 连接服务器
	if (0 != connect(SocketServer, (SOCKADDR *)&AddrServer, sizeof(SOCKADDR)))
	{
		closesocket(SocketServer);
		return false;
	}

	int err = 0;
	char temp[] = "hello, server";
	int rs = send(SocketServer, temp, sizeof(temp) + 1, 0);

	char buff[1024] = {0};
	rs = recv(SocketServer, buff, sizeof(buff), 0);

        // 下面这2句代码如果注释掉,后面的recv就能正解的返回0。如果不注释掉,recv就会返回-1,
         // 并得到10053这个错误
	rs = send(SocketServer, temp, sizeof(temp) + 1, 0);
	err = WSAGetLastError();

	rs = recv(SocketServer, buff, sizeof(buff), 0);
	err = WSAGetLastError();

	system("pause");
	return 0;
这个是服务器的:
	WORD    VersionRequested;
	WSADATA WsaData;

	VersionRequested = MAKEWORD(2, 2);

	if (WSAStartup(VersionRequested, &WsaData))
	{
		printf("加载socket库失败!\n");
		return -1;
	}

	// 监听来自浏览器的请求
	SOCKET SockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN AddrClient;
	AddrClient.sin_family      = AF_INET;
	AddrClient.sin_addr.s_addr = INADDR_ANY;
	AddrClient.sin_port        = htons(9999);

	if (SockServer == INVALID_SOCKET)
	{
		printf("socket初始化失败!\n");
		closesocket(SockServer);
		WSACleanup();
		return -1;
	}

	if (bind(SockServer, (sockaddr*)&AddrClient, sizeof(AddrClient)) != 0)
	{
		printf("socket绑定失败!\n");
		closesocket(SockServer);
		WSACleanup();
		return -1;
	}

	if (listen(SockServer, 10) != 0)
	{
		printf("socket监听失败!\n");
		closesocket(SockServer);
		WSACleanup();
		return -1;
	}

	while (1)
	{
		SOCKET NewSocket = accept(SockServer, NULL, NULL);
		if (INVALID_SOCKET == NewSocket)
		{
			closesocket(NewSocket);
			continue;
		}
		else
		{
			struct linger so_linger;
			so_linger.l_onoff  = 1;
			so_linger.l_linger = 30;
			setsockopt(NewSocket ,SOL_SOCKET, SO_LINGER, (const char*)&so_linger, sizeof(so_linger)); 
		}

		char buff[1024];
		int rs = recv(NewSocket, buff, sizeof(buff), 0);

		char temp[] = "hello, client";
		rs = send(NewSocket, temp, sizeof(temp) + 1, 0);

		closesocket(NewSocket);
	}
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



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值