许多解释都是表面的解释原因,说服务器端口没开等,防火墙阻挡等,其实,我遇到的问题并不是这样,看看我这个问题:
我做的是一个IOCP服务器程序跑在本机,同时我在本机有做了个client端程序,该client端程序用个循环不停的大量的连(调用connect函数)本机的IOCP服务器程序,若只跑client端程序的一个副本,一直连,没问题,但若跑client端程序的两个副本,一起连服务器,然后再杀死一个client副本,再一次启动client端的副本,这样折腾个1-2次,突然之间连接到服务器的client端就报10061错误,并且从此之后再也无法连接上IOCP服务器,我也很不理解为什么就突然连不上服务器了,于是我做了如下测试并做了猜想,这里也盼望高手给以解答:
(1)因为IOCP服务器和client都跑在本机,client端关闭了几次又重新运行几次,这样折腾了几个来回,导致client端程序的人为杀死影响了IOCP服务器程序对资源的需求(也许是IOCP服务器需要的一些网络资源被client占去)。
(2)我发现IOCP服务器此时的监听端口已经没有了,因为监听端口没了,所以client端连接肯定出10061错误。
(3)难道是我无意之间关闭了用来listen的socket?我把所有closesocket的地方全部作了判断,发现并没有close过服务器端的这个监听socket。
(4)我用的是acceptex来实现的iocp,难道acceptex的没有投递的缘故?经过测试,即使acceptex没有投递,正常情况下client仍然可以连接到IOCP服务器上去,只不过是无法收发信息罢了。
请各位朋友不吝啬赐教!
12 个解决方案
#1
关注
#2
WSAECONNREFUSED(10061)
No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running.
不知道你的“杀死一个client副本”是如何操作的,但最后造成的结果是server不再监听了
No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running.
不知道你的“杀死一个client副本”是如何操作的,但最后造成的结果是server不再监听了
#3
以前见过一次,我是服务器连接后马上关闭掉刚建立好的连接。
#4
问题补充:
(1)今日测试发现只要开两个client不停的连,那么只要这两个client程序(dos)窗口的有一个关闭,则另外一个的socket连接就出现10061错误。但是,已经连接上去的socket可以正常通讯,说明完成端口线程没有被意外退出,请看我的socket client端核心代码,非常粗糙,主要为测试:
//创建socket的循环等都省略
for( k1 = 0; k1 < CESHIXIBIAO; k1++) //500000
{
if( k1 !=0 && k1 % 5000 == 0)
Sleep(10000);
if (connect(sClient[k1], (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("connect() failed: %d, faile number is:%d\n", WSAGetLastError(),k1);
Sleep(5000);
//同时释放前面的某个
closesocket(sClient[k1 - 1000]);
//return 1;
continue;
}
else
{
printf("connect() success: number is:%d-----------------------\n", k1);
//return 1;
continue;
}
}
(2)杀死一个client副本的操作方法我是通过直接点DOS黑窗口右上角的X来关闭
(3)另外我杀死client的时机正好也是client执行代码拼命不断的连接server的时候,但通过client代码大家也能看到,我client只是不断连接服务器并保持住连接不切断,但并不向服务器发送任何信息。
(1)今日测试发现只要开两个client不停的连,那么只要这两个client程序(dos)窗口的有一个关闭,则另外一个的socket连接就出现10061错误。但是,已经连接上去的socket可以正常通讯,说明完成端口线程没有被意外退出,请看我的socket client端核心代码,非常粗糙,主要为测试:
//创建socket的循环等都省略
for( k1 = 0; k1 < CESHIXIBIAO; k1++) //500000
{
if( k1 !=0 && k1 % 5000 == 0)
Sleep(10000);
if (connect(sClient[k1], (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("connect() failed: %d, faile number is:%d\n", WSAGetLastError(),k1);
Sleep(5000);
//同时释放前面的某个
closesocket(sClient[k1 - 1000]);
//return 1;
continue;
}
else
{
printf("connect() success: number is:%d-----------------------\n", k1);
//return 1;
continue;
}
}
(2)杀死一个client副本的操作方法我是通过直接点DOS黑窗口右上角的X来关闭
(3)另外我杀死client的时机正好也是client执行代码拼命不断的连接server的时候,但通过client代码大家也能看到,我client只是不断连接服务器并保持住连接不切断,但并不向服务器发送任何信息。
#5
经过跟踪这种AcceptEX实现方式的IOCP,AcceptEX的实现方式和传统的accept是不太一样的,我竟然发现当client端拼命发起多个连接来连接服务器的时候杀掉整个client端(任务管理器中直接杀进程),可能会造成服务器在AcceptEX处理之前连接上又断掉(这些连接请求会保存在Listen socket的连接请求队列中),这个时候我发现服务器端GetQueuedCompletionStatus函数会返回0,表失败,同时,我发现GetLastError()返回的是64错误,这个表示指定的网络名不再可用错误,这个一般来讲都正常,因为你client端突然断开,所有连接到server的连接会导致服务器端产生大量的GetQueuedCompletionStatus返回0的情况,但是:
奇怪的问题是,在这些GetQueuedCompletionStatus返回0的情况中,我居然发现了listen套接字的socket句柄也在其中(我改了下整个程序,从而绝不closesocket,保证listen套接字绝对不是因为服务器程序closesocket引起),当listen套接字的socket句柄在其中的时候,server端监听端口消失,client也就再也无法连接。
各位朋友分析到过这种情况没?
奇怪的问题是,在这些GetQueuedCompletionStatus返回0的情况中,我居然发现了listen套接字的socket句柄也在其中(我改了下整个程序,从而绝不closesocket,保证listen套接字绝对不是因为服务器程序closesocket引起),当listen套接字的socket句柄在其中的时候,server端监听端口消失,client也就再也无法连接。
各位朋友分析到过这种情况没?
#6
难题解决,我理解错误。
GetQueuedCompletionStatus返回0,错误代码为64。
注意,我是每收到一个正常的ACCEPT请求后才在ACCEPT请求代码中再发起一个新的AcceptEx投递。
这里有个技术点,就是正常连接进来的socket会执行一系列ACCEPT请求代码(这些代码当然是由你写的),但若client拼命连接server,然后突然之间client端又被关闭,则服务器端会出现两种socket,这两种socket都是GetQueuedCompletionStatus返回0,错误代码为64的。
第一种就是已经正常连接进来的socket,这些正常连接进来的socket,我们只需要closesocket把他们关闭就行了,因为他们已经正常的执行了我的ACCEPT请求代码。
第二种就是“保存在Listen socket的连接请求队列中”的client socket,这些socket还没有来得及执行ACCEPT事件代码就被突然关闭的client端导致产生了GetQueuedCompletionStatus返回0,并且错误代码为64的错误,这种错误,我们的处理步骤是2个:
(1)关闭这个socket。
(2)发起新的AcceptEx请求以保证该IOCP线程可以收到新的连入请求。
GetQueuedCompletionStatus返回0,错误代码为64。
注意,我是每收到一个正常的ACCEPT请求后才在ACCEPT请求代码中再发起一个新的AcceptEx投递。
这里有个技术点,就是正常连接进来的socket会执行一系列ACCEPT请求代码(这些代码当然是由你写的),但若client拼命连接server,然后突然之间client端又被关闭,则服务器端会出现两种socket,这两种socket都是GetQueuedCompletionStatus返回0,错误代码为64的。
第一种就是已经正常连接进来的socket,这些正常连接进来的socket,我们只需要closesocket把他们关闭就行了,因为他们已经正常的执行了我的ACCEPT请求代码。
第二种就是“保存在Listen socket的连接请求队列中”的client socket,这些socket还没有来得及执行ACCEPT事件代码就被突然关闭的client端导致产生了GetQueuedCompletionStatus返回0,并且错误代码为64的错误,这种错误,我们的处理步骤是2个:
(1)关闭这个socket。
(2)发起新的AcceptEx请求以保证该IOCP线程可以收到新的连入请求。
#7
楼主的钻研精神令人佩服!学习了,
#8
结贴通知:
请lz注意结贴。。。。
请lz注意结贴。。。。
#9
遇到相同的问题 学习了
#10
遇到相同的问题 学习了
#11
遇到相同的问题 学习了
#12
遇到相同的问题,感谢楼主给了个思路!
#1
关注
#2
WSAECONNREFUSED(10061)
No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running.
不知道你的“杀死一个client副本”是如何操作的,但最后造成的结果是server不再监听了
No connection could be made because the target computer actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host—that is, one with no server application running.
不知道你的“杀死一个client副本”是如何操作的,但最后造成的结果是server不再监听了
#3
以前见过一次,我是服务器连接后马上关闭掉刚建立好的连接。
#4
问题补充:
(1)今日测试发现只要开两个client不停的连,那么只要这两个client程序(dos)窗口的有一个关闭,则另外一个的socket连接就出现10061错误。但是,已经连接上去的socket可以正常通讯,说明完成端口线程没有被意外退出,请看我的socket client端核心代码,非常粗糙,主要为测试:
//创建socket的循环等都省略
for( k1 = 0; k1 < CESHIXIBIAO; k1++) //500000
{
if( k1 !=0 && k1 % 5000 == 0)
Sleep(10000);
if (connect(sClient[k1], (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("connect() failed: %d, faile number is:%d\n", WSAGetLastError(),k1);
Sleep(5000);
//同时释放前面的某个
closesocket(sClient[k1 - 1000]);
//return 1;
continue;
}
else
{
printf("connect() success: number is:%d-----------------------\n", k1);
//return 1;
continue;
}
}
(2)杀死一个client副本的操作方法我是通过直接点DOS黑窗口右上角的X来关闭
(3)另外我杀死client的时机正好也是client执行代码拼命不断的连接server的时候,但通过client代码大家也能看到,我client只是不断连接服务器并保持住连接不切断,但并不向服务器发送任何信息。
(1)今日测试发现只要开两个client不停的连,那么只要这两个client程序(dos)窗口的有一个关闭,则另外一个的socket连接就出现10061错误。但是,已经连接上去的socket可以正常通讯,说明完成端口线程没有被意外退出,请看我的socket client端核心代码,非常粗糙,主要为测试:
//创建socket的循环等都省略
for( k1 = 0; k1 < CESHIXIBIAO; k1++) //500000
{
if( k1 !=0 && k1 % 5000 == 0)
Sleep(10000);
if (connect(sClient[k1], (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("connect() failed: %d, faile number is:%d\n", WSAGetLastError(),k1);
Sleep(5000);
//同时释放前面的某个
closesocket(sClient[k1 - 1000]);
//return 1;
continue;
}
else
{
printf("connect() success: number is:%d-----------------------\n", k1);
//return 1;
continue;
}
}
(2)杀死一个client副本的操作方法我是通过直接点DOS黑窗口右上角的X来关闭
(3)另外我杀死client的时机正好也是client执行代码拼命不断的连接server的时候,但通过client代码大家也能看到,我client只是不断连接服务器并保持住连接不切断,但并不向服务器发送任何信息。
#5
经过跟踪这种AcceptEX实现方式的IOCP,AcceptEX的实现方式和传统的accept是不太一样的,我竟然发现当client端拼命发起多个连接来连接服务器的时候杀掉整个client端(任务管理器中直接杀进程),可能会造成服务器在AcceptEX处理之前连接上又断掉(这些连接请求会保存在Listen socket的连接请求队列中),这个时候我发现服务器端GetQueuedCompletionStatus函数会返回0,表失败,同时,我发现GetLastError()返回的是64错误,这个表示指定的网络名不再可用错误,这个一般来讲都正常,因为你client端突然断开,所有连接到server的连接会导致服务器端产生大量的GetQueuedCompletionStatus返回0的情况,但是:
奇怪的问题是,在这些GetQueuedCompletionStatus返回0的情况中,我居然发现了listen套接字的socket句柄也在其中(我改了下整个程序,从而绝不closesocket,保证listen套接字绝对不是因为服务器程序closesocket引起),当listen套接字的socket句柄在其中的时候,server端监听端口消失,client也就再也无法连接。
各位朋友分析到过这种情况没?
奇怪的问题是,在这些GetQueuedCompletionStatus返回0的情况中,我居然发现了listen套接字的socket句柄也在其中(我改了下整个程序,从而绝不closesocket,保证listen套接字绝对不是因为服务器程序closesocket引起),当listen套接字的socket句柄在其中的时候,server端监听端口消失,client也就再也无法连接。
各位朋友分析到过这种情况没?
#6
难题解决,我理解错误。
GetQueuedCompletionStatus返回0,错误代码为64。
注意,我是每收到一个正常的ACCEPT请求后才在ACCEPT请求代码中再发起一个新的AcceptEx投递。
这里有个技术点,就是正常连接进来的socket会执行一系列ACCEPT请求代码(这些代码当然是由你写的),但若client拼命连接server,然后突然之间client端又被关闭,则服务器端会出现两种socket,这两种socket都是GetQueuedCompletionStatus返回0,错误代码为64的。
第一种就是已经正常连接进来的socket,这些正常连接进来的socket,我们只需要closesocket把他们关闭就行了,因为他们已经正常的执行了我的ACCEPT请求代码。
第二种就是“保存在Listen socket的连接请求队列中”的client socket,这些socket还没有来得及执行ACCEPT事件代码就被突然关闭的client端导致产生了GetQueuedCompletionStatus返回0,并且错误代码为64的错误,这种错误,我们的处理步骤是2个:
(1)关闭这个socket。
(2)发起新的AcceptEx请求以保证该IOCP线程可以收到新的连入请求。
GetQueuedCompletionStatus返回0,错误代码为64。
注意,我是每收到一个正常的ACCEPT请求后才在ACCEPT请求代码中再发起一个新的AcceptEx投递。
这里有个技术点,就是正常连接进来的socket会执行一系列ACCEPT请求代码(这些代码当然是由你写的),但若client拼命连接server,然后突然之间client端又被关闭,则服务器端会出现两种socket,这两种socket都是GetQueuedCompletionStatus返回0,错误代码为64的。
第一种就是已经正常连接进来的socket,这些正常连接进来的socket,我们只需要closesocket把他们关闭就行了,因为他们已经正常的执行了我的ACCEPT请求代码。
第二种就是“保存在Listen socket的连接请求队列中”的client socket,这些socket还没有来得及执行ACCEPT事件代码就被突然关闭的client端导致产生了GetQueuedCompletionStatus返回0,并且错误代码为64的错误,这种错误,我们的处理步骤是2个:
(1)关闭这个socket。
(2)发起新的AcceptEx请求以保证该IOCP线程可以收到新的连入请求。
#7
楼主的钻研精神令人佩服!学习了,
#8
结贴通知:
请lz注意结贴。。。。
请lz注意结贴。。。。
#9
遇到相同的问题 学习了
#10
遇到相同的问题 学习了
#11
遇到相同的问题 学习了
#12
遇到相同的问题,感谢楼主给了个思路!