GetQueuedCompletionStatus检测到客户端socket关闭,该socket重新打开之后如何继续保持通讯?

时间:2022-05-10 23:48:48
代码:
while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
  &BytesTransferred, 
  (LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
  INFINITE
  );
...
如果检测到客户端的socket关闭了(BytesTransferred= 0),为了避免内存泄漏,执行:
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
可是该socket重新打开之后也连不上服务器了,大家遇到过这样的问题吗?

14 个解决方案

#1


是该socket重新打开之后也连不上服务器了,大家遇到过这样的问题吗?
===
socket 重新打开不就相当于新的连接了吗? 
连不上服务器, 是不是服务器挂了啊

#2


不是的,其实把
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
注释掉,重新打开是可以连接的,只是最后退出的时候有内存泄漏。

#3


socket重新打开? 怎么操作的? 代码

#4


我以上的代码是服务器端的啊,我的客户端是另外一个程序。把客户端关闭重新打开就是了。

#5


while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
  &BytesTransferred, 
  (LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
  INFINITE
  );
...
如果检测到客户端的socket关闭了(BytesTransferred= 0),为了避免内存泄漏,执行:
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
==================================

在这段代码的中间如果没有哪里有问题的话, 那就非常奇怪. 
因为客户端只是断开连接, 然后重新打开, 就连不上服务器, 可以断定是服务器那边哪里没有处理好,好好检查一下. 

#6


直接closesocket(PerHandleData->hClntSock)是不能重用的!

#7


的确是不能重用 ,我在这里问的就是这个问题啊,大家有没有办法?客户端关闭后,如果不执行
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
程序退出时就会造成内存泄漏,我曾想过用 try,finally来解决这个问题,在finally里再释放内存,但是编译不能通过,我想可能是在线程函数里的缘故。
所以说,解决这个问题的两个办法:
1、在程序结束时在释放内存;
2、客户端关闭即释放内存,但客户端启动时重用。
下面是部分代码:
while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, 
  &BytesTransferred, 
  (LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
  INFINITE
  );

if(BytesTransferred==0) //EOF 
{


closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
continue;
}
...
}

#8


www.codeproject.com/internet上有许多IOCP的示例。

#9


你的
(LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
是临时变量??还是全局变量

并且从你的程序中看来,这两个变量管理着所有的socket,你free掉之后,其他socket怎么得到服务呀??

#10


To DentistryDoctor(MVP-My heart will fly,in the sky.):谢谢,我一会去看。

To nuaawenlin(飘人):以上代码是在一个线程函数里,线程可能被创建多个,所以两个变量都是在该线程函数里定义的。被free掉,socket的确不能取得数据了。只是我想这两个变量都是被GetQueuedCompletionStatus分配内存并初始化的,free掉以后难道GetQueuedCompletionStatus不能再一次给他们分配内存吗?

#11


判断一下bRet 的返回值, 并判断WSAGetLastError()返回什么. 根据其返回值bRet和后面那个就可以判断GetQueuedCompletionStatus是不是已经异常了

#12


不是重新打开吧,是新的一个套接字了。有没有再关联一次?

#13


striking(硬撑者-theCpp@hotmail.com)说的方法管用,用WSAGetLastError()判断,程序退出时返回ERROR_OPERATION_ABORTED,对方socket关闭时返回ERROR_PORT_UNREACHABLE,当返回ERROR_OPERATION_ABORTED时释放资源,ERROR_PORT_UNREACHABLE时不必理会,就可以了。谢谢大家的参与!下午结贴,看看大家还有没有要说的。

#14


看来我又要升级了, 丫的, 爽 ;)

#1


是该socket重新打开之后也连不上服务器了,大家遇到过这样的问题吗?
===
socket 重新打开不就相当于新的连接了吗? 
连不上服务器, 是不是服务器挂了啊

#2


不是的,其实把
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
注释掉,重新打开是可以连接的,只是最后退出的时候有内存泄漏。

#3


socket重新打开? 怎么操作的? 代码

#4


我以上的代码是服务器端的啊,我的客户端是另外一个程序。把客户端关闭重新打开就是了。

#5


while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
  &BytesTransferred, 
  (LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
  INFINITE
  );
...
如果检测到客户端的socket关闭了(BytesTransferred= 0),为了避免内存泄漏,执行:
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
==================================

在这段代码的中间如果没有哪里有问题的话, 那就非常奇怪. 
因为客户端只是断开连接, 然后重新打开, 就连不上服务器, 可以断定是服务器那边哪里没有处理好,好好检查一下. 

#6


直接closesocket(PerHandleData->hClntSock)是不能重用的!

#7


的确是不能重用 ,我在这里问的就是这个问题啊,大家有没有办法?客户端关闭后,如果不执行
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
程序退出时就会造成内存泄漏,我曾想过用 try,finally来解决这个问题,在finally里再释放内存,但是编译不能通过,我想可能是在线程函数里的缘故。
所以说,解决这个问题的两个办法:
1、在程序结束时在释放内存;
2、客户端关闭即释放内存,但客户端启动时重用。
下面是部分代码:
while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, 
  &BytesTransferred, 
  (LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
  INFINITE
  );

if(BytesTransferred==0) //EOF 
{


closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
continue;
}
...
}

#8


www.codeproject.com/internet上有许多IOCP的示例。

#9


你的
(LPDWORD)&PerHandleData,
  (LPOVERLAPPED*)&PerIoData, // OVERLAPPED 
是临时变量??还是全局变量

并且从你的程序中看来,这两个变量管理着所有的socket,你free掉之后,其他socket怎么得到服务呀??

#10


To DentistryDoctor(MVP-My heart will fly,in the sky.):谢谢,我一会去看。

To nuaawenlin(飘人):以上代码是在一个线程函数里,线程可能被创建多个,所以两个变量都是在该线程函数里定义的。被free掉,socket的确不能取得数据了。只是我想这两个变量都是被GetQueuedCompletionStatus分配内存并初始化的,free掉以后难道GetQueuedCompletionStatus不能再一次给他们分配内存吗?

#11


判断一下bRet 的返回值, 并判断WSAGetLastError()返回什么. 根据其返回值bRet和后面那个就可以判断GetQueuedCompletionStatus是不是已经异常了

#12


不是重新打开吧,是新的一个套接字了。有没有再关联一次?

#13


striking(硬撑者-theCpp@hotmail.com)说的方法管用,用WSAGetLastError()判断,程序退出时返回ERROR_OPERATION_ABORTED,对方socket关闭时返回ERROR_PORT_UNREACHABLE,当返回ERROR_OPERATION_ABORTED时释放资源,ERROR_PORT_UNREACHABLE时不必理会,就可以了。谢谢大家的参与!下午结贴,看看大家还有没有要说的。

#14


看来我又要升级了, 丫的, 爽 ;)