//设置KeepAlive
BOOL bKeepAlive = TRUE;
nRet = ::setsockopt(m_sockDesc, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeepAlive, sizeof(bKeepAlive));
if (nRet !=0)
{
sprintf(m_pszError, "Winsock error : %s (Error Code %d)\n ", "Socket SetOpt failed ", WSAGetLastError());
return FALSE;
}//设置KeepAlive检测时间和次数
TCP_KEEPALIVE inKeepAlive = {0}; //输入参数
unsigned long ulInLen = sizeof(TCP_KEEPALIVE); TCP_KEEPALIVE outKeepAlive = {0}; //输出参数
unsigned long ulOutLen = sizeof(TCP_KEEPALIVE); unsigned long ulBytesReturn = 0;//设置socket的keep alive为10秒,并且发送次数为3次
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 10000; //两次KeepAlive探测间的时间间隔
inKeepAlive.keepalivetime = 3; //开始首次KeepAlive探测前的TCP空闭时间nRet = WSAIoctl(m_sockDesc,
SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive,
ulInLen,
(LPVOID)&outKeepAlive,
ulOutLen,
&ulBytesReturn,
NULL,
NULL);
if(SOCKET_ERROR == nRet)
{
sprintf(m_pszError, "Winsock error : %s (Error Code %d)\n ", "Nonblocking socket call error ", WSAGetLastError());
return FALSE;
}这是一段设置系统默认心跳包的代码,有一点不太清楚。这么处理心跳包的返回。当心跳包探测到对方不在了(如何判断),我想做一些自己定义的动作,这些动作我应该写到什么地方。
BOOL bKeepAlive = TRUE;
nRet = ::setsockopt(m_sockDesc, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeepAlive, sizeof(bKeepAlive));
if (nRet !=0)
{
sprintf(m_pszError, "Winsock error : %s (Error Code %d)\n ", "Socket SetOpt failed ", WSAGetLastError());
return FALSE;
}//设置KeepAlive检测时间和次数
TCP_KEEPALIVE inKeepAlive = {0}; //输入参数
unsigned long ulInLen = sizeof(TCP_KEEPALIVE); TCP_KEEPALIVE outKeepAlive = {0}; //输出参数
unsigned long ulOutLen = sizeof(TCP_KEEPALIVE); unsigned long ulBytesReturn = 0;//设置socket的keep alive为10秒,并且发送次数为3次
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 10000; //两次KeepAlive探测间的时间间隔
inKeepAlive.keepalivetime = 3; //开始首次KeepAlive探测前的TCP空闭时间nRet = WSAIoctl(m_sockDesc,
SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive,
ulInLen,
(LPVOID)&outKeepAlive,
ulOutLen,
&ulBytesReturn,
NULL,
NULL);
if(SOCKET_ERROR == nRet)
{
sprintf(m_pszError, "Winsock error : %s (Error Code %d)\n ", "Nonblocking socket call error ", WSAGetLastError());
return FALSE;
}这是一段设置系统默认心跳包的代码,有一点不太清楚。这么处理心跳包的返回。当心跳包探测到对方不在了(如何判断),我想做一些自己定义的动作,这些动作我应该写到什么地方。
解决方案 »
- 在对话框中显示caret的问题
- MFC学习资料
- 有MMORPG开发经验的请进,简单问题
- socket编程触发接收问题....望高手帮帮忙!!!!!!!!!!!
- 列表控件的view属性在哪啊
- 不知道vc++和c++builder有没有太大的差别??(中学生提问)
- 有谁知道.pdg格式的书用什么程序打开????
- _waccess 这个函数怎么用的啊?
- 怎样用VC编程得到本机的IP地址?我知道在VB中用Text1.Text = Winsock1.LocalIP
- 送100分!怎样用VC++作坐标图,画出工厂每月产量,X轴为是一月。二月,。Y轴是是产量,1吨,2吨,
- BCG和MFC的CDialog不同
- 关于CRichEditCtrl的undo的问题
if(GetQueuedCompletionStatus(CompletionPort, BytesTransferred,DWORD(PerHandleData),
POverlappe(PerIoData),INFINITE) = FALSE)
{
//这里处理断线
}
如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。 发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。
一般来说,出于效率的考虑,是由客户端主动向服务器端发包,而不是相反。 心跳包是用户数据包,与协议无关,所以会发送数据就会发送心跳包,格式自定义。
心跳包也可以用来占领住IP资源,达到永远在线的目的。
比如:在移动上网时,IP是一种有限的紧张的资源,电信会把已分配的但长时间未使用的IP回收回来,所以要发心跳包告诉电信,我的IP仍然在使用中。
-----------------------------------------------
http://www.wantsoft.com
隐形者软件代码交流博客
-----------------------------------------------
注意:心跳线程可以处理所有客户端的连接。
http://topic.csdn.net/u/20081108/15/cf8db1e7-8a9c-4e2c-9472-440cce8babec.html
1.每个客户端上线时,发出的事件m_hEvent
2.接受到客户连接请求时,开启一个定时器m_hTimer
3.主线程退出时,通知心跳线程退出事件的m_hExitEvent;
4.客户列表(包含每个客户的事件,等待定时器,ProjNum),ProjNum对于每个客户地址当有第一个客户上线时,定时一个事件m_hEvent,然后启动心跳线程,在心跳线程中使用WaitForMutiplyObjects等待事件变成信号的,
当事件有信号时,使用CreateWaitableTimer创建定时器,然后再使用SetWaitableTimer来设置定时器。
当有客户第二个发送消息时,会再设置m_hEvent为信号状态,这时心跳线程使用Waitfor返回后,使用SetWaitableTimer刷新定时器的等待时间,那么等待时间重新变成30秒
当某个客户过了30秒还没有发消息过来,就定时器会变成信号态的,这时心咣线程使用WaitForMutiplyObjects等待定时器会返回一个定时器索引,之后心跳线程会移除客户列表中某个成员
当有客户下线时,会发送一个特定消息,心跳线程处理这个消息时,直接将某个客户从列表中移除。
当所有客户都下线时,主线程使用m_hExitEvent通知心跳线程来关闭自身注意:我这个示例中没有心跳线程向客户端回发消息的处理,添加时需要在接收到m_hEvent之后回发消息。
WaitForMutiplyObjects最多接收64个客户,如果有更多客户上线时,需要当客户列表分段来循环等待。