connect(s,(sockaddr*)&addr,sizeof(SOCKADDR_IN));
ULONG arg=1;
ioctlsocket(s,FIONBIO,&arg);
int timeout=2000;
setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
int ret=recv(s,buf,buf_len,0);
while(ret=SOCKET_ERROR && WSAGetLastError()==WSAEWOULDBLOCK)Sleep(100);
recv不会返回WSAETIMEOUT,如果设置为阻塞,就会返回WSAETIMEOUT。
情况是这样的:
我打算用select模式来管理多个连接,需要检查在select中的各个连接是否超时。如果setsockopt无法给非阻塞socket设置超时,目前想到的办法只有在select中设置一个比较短的超时值,等select返回后遍历每个连接,来检查是否超时,非常不爽。
14 个解决方案
#1
再详细说一下我的目的。
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
请大家给个思路。
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
请大家给个思路。
#2
因为是非阻塞的,那么就需要你自己来判断连接是否有效了
#3
是的。
请问setsockopt是否可以设置非阻塞套接字超时?如果不可以,关于我上面的问题,有没有有效的解决办法?事实上,同样的问题应该也存在在完成端口上。
#4
帮顶
#5
帮顶
#6
没有人理吗?感觉这个问题应该很常见啊?大家都用过什么办法来解决?
#7
C/S 分别向对方定期的发送一个很短的保活请求,同时记录如果再多少次没有收到对方的请求后就可判定对方是否超时,可以断掉链接。
#8
LS,我不是问怎样判断连接是否超时,我是问在用select后者完成端口时,当同时对多个连接进行IO时,如何有效的处理超时。详细见顶楼
#9
没人遇到这样的问题吗
#10
ding
#11
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
你的问题已经被你的前提限制死了。select不应该这样用的,你这种情况很难用select满足需求。
如果select只是用来处理多个连接跳转,建议放弃起selcet,转用多线程加阻塞模式,超时自己退出该线程,断开该连接。
不过可能并发的连接数太多,会比较卡。。
你的问题已经被你的前提限制死了。select不应该这样用的,你这种情况很难用select满足需求。
如果select只是用来处理多个连接跳转,建议放弃起selcet,转用多线程加阻塞模式,超时自己退出该线程,断开该连接。
不过可能并发的连接数太多,会比较卡。。
#12
mark
#13
我现在就是多线程阻塞,在线程里面对单个SOCKET用SELECT来监测超时。就像你说的那样,并发连接太多就讨厌了。
没有别的办法了吗?
#14
学习一下
#1
再详细说一下我的目的。
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
请大家给个思路。
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
请大家给个思路。
#2
因为是非阻塞的,那么就需要你自己来判断连接是否有效了
#3
是的。
请问setsockopt是否可以设置非阻塞套接字超时?如果不可以,关于我上面的问题,有没有有效的解决办法?事实上,同样的问题应该也存在在完成端口上。
#4
帮顶
#5
帮顶
#6
没有人理吗?感觉这个问题应该很常见啊?大家都用过什么办法来解决?
#7
C/S 分别向对方定期的发送一个很短的保活请求,同时记录如果再多少次没有收到对方的请求后就可判定对方是否超时,可以断掉链接。
#8
LS,我不是问怎样判断连接是否超时,我是问在用select后者完成端口时,当同时对多个连接进行IO时,如何有效的处理超时。详细见顶楼
#9
没人遇到这样的问题吗
#10
ding
#11
我的需求比较奇特,不是一个server,不需要listen,但我需要同时保持对多个(200+)个server的连接,而且是长连接。所以采用select模式。每个连接读写数据的时间不定,但我希望给每个连接添加一个超时,比如某次读写操作发出之后,1分钟之后操作还没有进行(就是对这个连接的select操作没有返回),就认为这个连接已经死了,需要断掉重新连接。
你的问题已经被你的前提限制死了。select不应该这样用的,你这种情况很难用select满足需求。
如果select只是用来处理多个连接跳转,建议放弃起selcet,转用多线程加阻塞模式,超时自己退出该线程,断开该连接。
不过可能并发的连接数太多,会比较卡。。
你的问题已经被你的前提限制死了。select不应该这样用的,你这种情况很难用select满足需求。
如果select只是用来处理多个连接跳转,建议放弃起selcet,转用多线程加阻塞模式,超时自己退出该线程,断开该连接。
不过可能并发的连接数太多,会比较卡。。
#12
mark
#13
我现在就是多线程阻塞,在线程里面对单个SOCKET用SELECT来监测超时。就像你说的那样,并发连接太多就讨厌了。
没有别的办法了吗?
#14
学习一下