主要就是一种超时检测机制,很多服务器程序都需要这样的机制,因为太多空闲的连接还是使用一定量的系统资源的,有些服务器,象FTP服务器,有时还限制了最大登陆的连接数,万一有人恶意大量地连接,但这些连接不被系统定时断开的话,那么正常的用户有可能无法登陆FTP服务器(因为连接数到达上限)
1.使用setsockopt设置SO_RCVTIMEO
这种方法简单好用,但缺点是只用于阻塞的socket,而且有时因为对方的非正常断开而无法检测到.
2.在接收数据前使用select(),select()返回可读才调用recv()等API.
这种方法一样简单好用,但缺点还是主要适用于阻塞socket,一般非阻塞socket也可用,只不过要调用个死循环不断地检测select()返回值,很是浪费资源.
3.定时扫描所有客户socket的方法(楼主正采用的方法).这方法就是记录每次每个socket数据通讯时的时间,然后在扫描时再和当前时间比较,如果时间差高于超时机制的限制时间,就将socket断开.
这种方法使用起来也是很简单的,只要建一个线程定时地扫描所有客户socket列表.适用性很强,所有socket模式都可兼容的.需要注意的是这方法临界要做好,不然是挺容易出现问题(在扫描期间有socket正常的断开时资源被释放时,扫描列表时如果没做临界,那么扫描时就很有可能访问了非法的内存).这方法有个缺点就是超时机制的误差比较高,因为如果超时检测的时间设置为N,那么是有可能出现N-1秒的误差的.设置检测的时间越长,出现的误差时间就越长.由于每次都要扫描所有的客户socket列表,如果socket比较多时,设置这个检测时间就是个"鸡肋".检测时间设置得过短,频烦的扫描对系统资源和程序性能必然多少有是影响;而设置时间过长,又令误差时间过大.
4.使用系统的Timer
标准的Timer:使用SetTimer()设置Timer,使用KillTimer()删除Timer.优点是适用于所有系统,也适用于所有socket模型.缺点是精确度不高,而且是消息机制的,如果太多消息要处理,Timer触发时间会被延迟.
NT系统内核Timer.优点是精确度高,缺点是只能用于NT系统.