完成端口,如何判断客户端异常断开?

djfu 2009-03-10 08:56:43
有些情况通过GetQueuedCompletionStatus是无法得知客户端连接已经异常断开的,
比如:客户端网线突然被拔了。

这时如何判断客户端连接已经断开?
这时send还是可以成功的,尽管连接已经断了。
...全文
678 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
无间兔 2009-03-27
  • 打赏
  • 举报
回复
设置WSAIoctl的保活项SIO_KEEPALIVE_VALS,注意SIO_KEEPALIVE_VALS项的输入参数是个结构体struct tcp_keepalive {
u_long onoff; 非零数启用保活并使后续参数有效
u_long keepalivetime; 首次保活探测包发送前的空闭时间(ms)
u_long keepaliveinterval; 发送保活探测包的间隔时间(ms)
};使用该结构要包含mstcpip.h文件。
WSAIoctl还有个好处就是只针对当前socket进行设置。
路人乙2019 2009-03-27
  • 打赏
  • 举报
回复
用心跳是好,不过客户端太多了势必会加重服务端的工作.
saiyaman5 2009-03-27
  • 打赏
  • 举报
回复
学习下
WinEggDrop 2009-03-26
  • 打赏
  • 举报
回复
加入超时检测机制.某一段时间内(例如5分钟),连接都没有数据交换,定义为超时,不论是不是异常断开还是挂着没数据,一律断开.
stivenjia 2009-03-26
  • 打赏
  • 举报
回复
GetQueuedCompletionStatus之后再select一下
coast1 2009-03-26
  • 打赏
  • 举报
回复
心跳检测
总哈哈 2009-03-26
  • 打赏
  • 举报
回复
心跳和定时检测一个意思,两者都行!
百事烟 2009-03-24
  • 打赏
  • 举报
回复
心跳
wanglovec 2009-03-24
  • 打赏
  • 举报
回复
心跳检测
caohongtai 2009-03-24
  • 打赏
  • 举报
回复
ping 一下(用程序ping)
reality 2009-03-24
  • 打赏
  • 举报
回复
自己检测
djfu 2009-03-11
  • 打赏
  • 举报
回复
楼上的, 你这个不行,
我说了, 根据GetQueuedCompletionStatus不能得出网络是否异常掉线的结果。

我把客户端网线拔了,服务端无法通过GetQueuedCompletionStatus得出是否客户端已经掉线的结论。
vagrantisme 2009-03-10
  • 打赏
  • 举报
回复

BOOL bIORet = GetQueuedCompletionStatus(
hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped, INFINITE);
// Simulate workload (for debugging, to find possible reordering)
//Sleep(20);



// If Something whent wrong..
if (!bIORet)
{
DWORD dwIOError = GetLastError();
if(dwIOError != WAIT_TIMEOUT) // It was not an Time out event we wait for ever (INFINITE)
{
TRACE(_T("GetQueuedCompletionStatus errorCode: %i, %s\n"),WSAGetLastError(),pThis->ErrorCode2Text(dwIOError));
// if we have a pointer & This is not an shut down..
//if (lpClientContext!=NULL && pThis->m_bShutDown == false)
if (lpClientContext!=NULL)
{
/*
* ERROR_NETNAME_DELETED Happens when the communication socket
* is cancelled and you have pendling WSASend/WSARead that are not finished.
* Then the Pendling I/O (WSASend/WSARead etc..) is cancelled and we return with
* ERROR_NETNAME_DELETED..
*/
if(dwIOError==ERROR_NETNAME_DELETED)
{

//TRACE("ERROR_NETNAME_DELETED\r\n");
pThis->DisconnectClient(lpClientContext);
TRACE(">IOWORKER1 (%x)\r\n",lpClientContext);
pThis->ReleaseClientContext(lpClientContext); //Later Implementati

}else
{ // Should not get here if we do: disconnect the client and cleanup & report.

pThis->AppendLog(pThis->ErrorCode2Text(dwIOError));
pThis->DisconnectClient(lpClientContext);
TRACE(">IOWORKER2 (%x)\r\n",lpClientContext);
pThis->ReleaseClientContext(lpClientContext); //Should we do this ?
}
// Clear the buffer if returned.
pOverlapBuff=NULL;
if(lpOverlapped!=NULL)
pOverlapBuff=CONTAINING_RECORD(lpOverlapped, CIOCPBuffer, m_ol);
if(pOverlapBuff!=NULL)
pThis->ReleaseBuffer(pOverlapBuff);
continue;
}
// We shall never come here
// anyway this was an error and we should exit the worker thread
bError = true;
pThis->AppendLog(pThis->ErrorCode2Text(dwIOError));
pThis->AppendLog("IOWORKER KILLED BECAUSE OF ERROR IN GetQueuedCompletionStatus");

pOverlapBuff=NULL;
if(lpOverlapped!=NULL)
pOverlapBuff=CONTAINING_RECORD(lpOverlapped, CIOCPBuffer, m_ol);
if(pOverlapBuff!=NULL)
pThis->ReleaseBuffer(pOverlapBuff);
continue;
}
}
vagrantisme 2009-03-10
  • 打赏
  • 举报
回复
BOOL bIORet = GetQueuedCompletionStatus(
hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped, INFINITE);
// Simulate workload (for debugging, to find possible reordering)
//Sleep(20);



// If Something whent wrong..
if (!bIORet)
{
DWORD dwIOError = GetLastError();
if(dwIOError != WAIT_TIMEOUT) // It was not an Time out event we wait for ever (INFINITE)
{
TRACE(_T("GetQueuedCompletionStatus errorCode: %i, %s\n"),WSAGetLastError(),pThis->ErrorCode2Text(dwIOError));
// if we have a pointer & This is not an shut down..
//if (lpClientContext!=NULL && pThis->m_bShutDown == false)
if (lpClientContext!=NULL)
{
/*
* ERROR_NETNAME_DELETED Happens when the communication socket
* is cancelled and you have pendling WSASend/WSARead that are not finished.
* Then the Pendling I/O (WSASend/WSARead etc..) is cancelled and we return with
* ERROR_NETNAME_DELETED..
*/
if(dwIOError==ERROR_NETNAME_DELETED)
{

//TRACE("ERROR_NETNAME_DELETED\r\n");
pThis->DisconnectClient(lpClientContext);
TRACE(">IOWORKER1 (%x)\r\n",lpClientContext);
pThis->ReleaseClientContext(lpClientContext); //Later Implementati

}else
{ // Should not get here if we do: disconnect the client and cleanup & report.

pThis->AppendLog(pThis->ErrorCode2Text(dwIOError));
pThis->DisconnectClient(lpClientContext);
TRACE(">IOWORKER2 (%x)\r\n",lpClientContext);
pThis->ReleaseClientContext(lpClientContext); //Should we do this ?
}
// Clear the buffer if returned.
pOverlapBuff=NULL;
if(lpOverlapped!=NULL)
pOverlapBuff=CONTAINING_RECORD(lpOverlapped, CIOCPBuffer, m_ol);
if(pOverlapBuff!=NULL)
pThis->ReleaseBuffer(pOverlapBuff);
continue;
}
// We shall never come here
// anyway this was an error and we should exit the worker thread
bError = true;
pThis->AppendLog(pThis->ErrorCode2Text(dwIOError));
pThis->AppendLog("IOWORKER KILLED BECAUSE OF ERROR IN GetQueuedCompletionStatus");

pOverlapBuff=NULL;
if(lpOverlapped!=NULL)
pOverlapBuff=CONTAINING_RECORD(lpOverlapped, CIOCPBuffer, m_ol);
if(pOverlapBuff!=NULL)
pThis->ReleaseBuffer(pOverlapBuff);
continue;
}
}

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧