LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1713|回复: 7

請問如何判斷socket斷線?

[复制链接]
发表于 2004-11-17 13:41:01 | 显示全部楼层 |阅读模式
FD_ZERO(&rset);
for(listnum=0;listnum<SerNum;listnum++) {
   if(connectlist[listnum] != 0) {
      FD_SET(connectlist[listnum], &rset);
      if(connectlist[listnum] > highsock)
         highsock = connectlist[listnum];
   }
}

timeout.tv_sec = 1;
timeout.tv_usec = 0;

int i = select (highsock+3, &rset, Null, (fd_set *)0, &timeout);
if(i < 0) {
   printf("select error\n");
   return;
}
else if(i == 0) {
   printf("Time Out.\n");
   return;
}
else { //read data
   for(i=0;i<SerNum;i++) {
      if(FD_ISSET(connectlist, &rset)) { //有資料可讀
         n = recv(connectlist, &readbuf[size-left], left, 0);
         if(n<=0)
            printf("socket disconnect\n");
      }
   }  
}

socket is nonblocking socket.
同時select多條socket, 當有一條socket當掉, 因其他socket正常, 所以select回傅大於零的值就會進入read data裡. 用FD_ISSET?砼袛嗄且粋socket有資料可讀才讀. 所以那一個當掉的socket一直都沒有辦法偵測到.
請問有什麼好的辦法?韨蓽y有socket當掉或太久沒有在傅資料呢?
希望大家多多指教, 謝謝.
复制代码
发表于 2004-11-18 08:56:50 | 显示全部楼层
不用select行吗?

用单独的thread或process处理每个socket,用blocking socket,

这样不是容易判断了吗?
 楼主| 发表于 2004-11-18 09:13:28 | 显示全部楼层
是可以, 只是當要接收非常多的socket的時候, 產生很多的thread或process會很占cpu.
发表于 2004-11-19 20:08:39 | 显示全部楼层
UNP里说,socket有错误待处理时,select返回后该套接字既可读又可写
你可以加一个wset,呵呵,把
int i = select (highsock+3, &rset, Null, (fd_set *)0, &timeout);
改成
int i = select (highsock+3, &rset, &wset, (fd_set *)0, &timeout);
然后检查rset和wset对应的位是否同时置1,如果是那就是出错了
不过我没测试过哦,有结果告诉大家一声
发表于 2004-11-19 20:22:11 | 显示全部楼层
<x11> Westwind, 有啥好办法么
<-- robin (robin.jim@218.108.105.LinuxFire-17651) has left #linuxfire
--> robin (robin.jim@218.108.105.LinuxFire-17651) has joined #linuxfire
<Westwind> ?
--> fish (powerli@222.18.8.Linuxfans-7462) has joined #linuxfire
<Westwind> 这个好办
<Westwind> 第一,对方关闭连接,select肯定返回套接口可读
<fish> 听说这里很多人都用fvwm桌面管理器,我也装了,但是中文字体加载的时候有问题,不知道怎么解决?
--> pangwa (guang@210.46.9.Linuxfans-165) has joined #linuxfire
<Westwind> 如果读返回0则可断定该套接口已经断开连接了
<Westwind> 其它socket读应该返回一个正数,或者-1(errno 等于EWOULDBLOCK)
<Westwind> 绝对不可能返回0
<Westwind> int i = select (highsock+3, &rset, Null, (fd_set *)0, &timeout)
<Westwind> 这行为什么要加3
--> Whisper (Administra@202.174.50.Linuxfans-8286) has joined #linuxfire
<Westwind> 加一是正确的
<Westwind> if(connectlist[listnum] != 0) {
<Westwind> 这行也有问题
<Westwind> 因为如果SOCKET调用失败
<Westwind> 这个套接字是负数
<Westwind> 但这里显然他将创建失败的套接字也加入到了rset中了
<Westwind> 这行还有错误
<Westwind> 一个守护进程会关闭它的0,1,3描述字
<Westwind> 一个守护进程会关闭它的stdout,stdin,stderr描述字
<Westwind> 而他创建的第一个socket就应该返回0
<Westwind> 所以如果这样的状况他也肯定判断出错
<Westwind> 反正他的错误海了
<Westwind> 我就不说了
<Westwind> 我干活去
发表于 2004-11-19 20:33:14 | 显示全部楼层
对方关闭连接不算socket错误的话,我说的估计不起作用
 楼主| 发表于 2004-11-23 16:56:34 | 显示全部楼层
int i = select (FD_SETSIZE, &rset, &wset, (fd_set *)0, &timeout);
然后检查rset和wset对应的位是否同时置1,如果是那就是出错了

我試了, 當socket正常時, rset和wset对应的位都是1呀.所以這辦法還是不行呀.
发表于 2004-11-23 18:23:27 | 显示全部楼层
看来还是要读一下才知道
按照UNP和westwind所说,出错时肯定可读
不会像你说的那样“所以那一個當掉的socket一直都沒有辦法偵測到. ”
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表