我用心跳去检测客户端.这个时候把客户端那台机的网线拨掉.我的心跳WSASend返回值一样是"永远"成功.GetQueuedCompletionStatus也永远都是成功的.我查了一些资料,听了网友们的建议,说是投递一个读操作.OK,我在发心跳包后又投递了一个WSARecv.GetQueuedCompletionStatus永远都没有读的反应.这个时候,我把客户机的网线插上,GetQueuedCompletionStatus就猛烈的跳出读操作..我汗...完全没办法判断.求助.
调试欢乐多
比如perHandle和perIO,这两个东西都是GetQueuedCompletionStatus填充给我,我才能删的啊.这个时候我尝试了把这些地址都保存到结构里面,OK,可以删除了.但是一删除后,GetQueuedCompletionStatus马上就有反应了.这个时候向下执行,perHandle和perIO就都是空地址了,就报错了.这个是大问题,怎么释放空间???????
还有大问题,就是,我判断到断线之后,我怎么样去释放那些new出来的空间啊?
比如perHandle和perIO,这两个东西都是GetQueuedCompletionStatus填充给我,我才能删的啊.这个时候我尝试了把这些地址都保存到结构里面,OK,可以删除了.但是一删除后,GetQueuedCompletionStatus马上就有反应了.这个时候向下执行,perHandle和perIO就都是空地址了,就报错了.这个是大问题,怎么释放空间???????********************************************************************个人观点,未经测试,仅供参考:)你检测到网线断开后就应该显示的关闭套接字啊,关闭后GetQueuedCompletionStatus应该就能返回你原来投递的数据了,这时你可以释放资源。
你检测到网线断开后就应该显示的关闭套接字啊,关闭后GetQueuedCompletionStatus应该就能返回你原来投递的数据了,这时你可以释放资源。
-------------------------------------------------
谢谢,我试过了,关闭SOCKET后,GetQueuedCompletionStatus无任务响应.....
你检测到网线断开后就应该显示的关闭套接字啊,关闭后GetQueuedCompletionStatus应该就能返回你原来投递的数据了,这时你可以释放资源。
-------------------------------------------------
谢谢,我试过了,关闭SOCKET后,GetQueuedCompletionStatus无任务响应.....********************************************************************你要释放的资源是哪端的啊!服务器还是客户端?
这和采用什么模型根本没有关系,由于TCP协议本身的问题
必须由你自己的协议检测连接是否依然正常,也就是必须由你自己的协议来保证不要去使用心跳包,使用那个东西,你做出来的服务器只能是理论上的
应该用你自己的协议来保证网络的检测
这和采用什么模型根本没有关系,由于TCP协议本身的问题
必须由你自己的协议检测连接是否依然正常,也就是必须由你自己的协议来保证这个东西不能这么说, 对方异常断线, 服务器需要2msl 才能真正知道。 75s很长啊。
所以大家主要想知道一个快速判断的办法 so_keepalive 并不通用。steven 说看实现。不要去使用心跳包,使用那个东西,你做出来的服务器只能是理论上的
应该用你自己的协议来保证网络的检测msn 的做法 就是靠逻辑层心跳 30s 内必须有"PNG 命令" 进行逻辑判断。纯粹的判断数据是否到达客户端并无太大意义,steven 举过很多例子, 数据到来对方的tcp 栈 但是没有到逻辑层系统就崩溃了。 所以用心跳才更加有意义。但我目前想知道的是 如何定时,和如何删掉端口。
你能给分吗,给分我就回答你的问题,呵呵,开玩笑了1. struct time_node{
long id; // 用户ID
unsigned long timeout;
}
2. 服务器接收到一个用户的心跳包时,从时间链表中删除自己的时间节点,然后计算并更新新的超时值,然后放到时间链表的尾部(也就是说时间小的一定在链表的前端)
3. 开辟一个线程,该线程每隔1秒钟检测一次时间链表
4. 检测线程从链表中区出元素和当前时间比较,如果比当前时间小则说明该用户已经超时了然后继续取下一个元素,直到找到比当前时间大的元素然后 Sleep 1秒
上面是大致的过程,写得比较乱,对付看吧 呵呵
而且当有其他问题出现,需要删除某个端口的时候,又需要在这个队列遍历一次,去除所有long id;
*******************************************************为什么要这么做呢? 其实可以很简单啊
指的平均值而且当有其他问题出现,需要删除某个端口的时候,又需要在这个队列遍历一次,去除所有long id;当一个端口被删除,需要删除掉所有相关的定时器吧。 不然到时候定时器到了,取到的数据就已经失效了。被删除了
{
public:
list_node *next;
list_node *prev;
}
在为每个连接(客户端)建立一个类class client
{
public:
long id;
int sock;
unsigned long time_out;
list_node node;
}
你说我在删除的时候容易不?
是这个吗?http://community.csdn.net/Expert/TopicView3.asp?id=5209711多次投递,没找到阿,贴个连接出来