2003-12-19 09:54
无双
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1--><br />/* See what's going on with a socket -- is the connection still valid? */<br />int S5IOCheck(S5IOHandle fd) {<br /> struct timeval tv = { 0, 0 };<br /> fd_set rfds, b;<br /> char dummy;<br /> int sv, n;<br /> <br /> FD_ZERO(&b);<br /> FD_SET(fd, &b);<br /><br /> S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "S5IOCheck: Checking socket status");<br /><br /> /* Poll the file descriptor real quick, and see what comes back... */<br /> while (1) {<br /> rfds = b; <br />//使用select来判断<br /> switch ((sv = REAL(select)(fd+1, &rfds, NULL, NULL, &tv))) {<br /> case 1:<br />//如果激活时<br /> /* Something happened -- either an error or data, ok to recv */<br />使用msg_peer来保留数据在端口中,不影响其它函数的调用<br /> n = RECVSOCKET(fd, &dummy, 1, MSG_PEEK);<br />//如果是EINTR(收到中断) 那跳过 继续检查<br /> if (n < 0 && ISSOCKETERROR(EINTR)) continue;<br /> else if (n <= 0) {<br /> S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(1), 0, "S5IOCheck: recv failed: %m");<br /> return -1;<br /> }<br /> /* fallthrough -- there is real data there... */<br /> case 0:<br /> /* Nothing's happening -- no error, all's ok. */<br />如果是0 没有激活 那就不等它了 返回OK<br /> S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "S5IOCheck: ok");<br /> return sv;<br /> default:<br /> /* Not a valid socket (?). */<br />-1 这是肯定出错了 不用想 返回错误<br /> if (ISSOCKETERROR(EINTR)) continue;<br /> S5LogUpdate(S5LogDefaultHandle, S5_LOG_WARNING, 0, "S5IOCheck: select failed: %m");<br /> return -1;<br /> }<br /> }<br />}<br /><!--c2--></div><!--ec2-->
2003-12-19 14:17
ManInBlack
select检测不出如下状况下的socket状态:<br />1、拔网线<br />2、C/S互连状态下,S改变listen socket的监听端口,然后S关闭与C的客户socket(没有用shutdown和closesocket正常关闭),接着C请求与S交互(自然无响应),然后S再恢复listen socket的监听端口为原端口,这时C检测不到当前socket已经无效了。<br /><br />我现在就碰到这样的问题。<br />我的S端被设计成为每一个客户socket开启一个任务线程去处理,这个线程通常可以直接被强制关闭而不释放任何资源,而且这被设计为是合理的情况。因此需要由C端主动检测到自己与S的关联资源是否有效(比如socket),所以就有了我的这些问题。
2003-12-22 14:46
ManInBlack
我没说清楚,再说一遍,问题得实质是:<br />题设:<br />客户机有两个任务TA和TB,TA申请了一个套接字,描述符为FDA,TB申请了一个套接字,描述符为FDB,而且恰好FDB=FDA+1。TA和TB都是外部消息驱动的,也就是只有外部消息到达时,才会触发套接字操作。<br /><br />问题:<br />当由于某种原因,服务器把对应与该客户机的两个套接字FDA和FDB的套接字都关闭掉。然后恰好客户机上TB任务的外部消息先于TA任务到达,于是TA会检测到FDB失效,然后释放该套接字资源并重新申请一个套接字FDB_NEW,结果经过DEBUG发现恰好有FDB_NEW=FDA成立。于是当TA检测FDA时,却没有发现FDA已经失效了(因为实际上此时的FDA就是FDB_NEW),结果TA和TB使用了同一个套接字描述符,造成了会话乱序(因为会话规则建立在一个任务使用一个专有套接字的基础上)。<br /><br />所以,我想问的是:有什么办法可以保证申请到的套接字描述符不是系统曾经分配过的?<br /><br />速回!!