LinuxSir.cn,穿越时空的Linuxsir!

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

请教一下I/O复用

[复制链接]
发表于 2005-2-5 17:42:50 | 显示全部楼层 |阅读模式
我用的是select()。
可现在的问题是如果套接字集中的一个TCP连接的另一方已经关闭,那么怎样才能把这个套接字从这个调接字集中删掉。
我试了一下FD_CLR这个宏,似乎不能完成上面的要求。
请问该怎么做?
发表于 2005-2-6 08:12:32 | 显示全部楼层
Post by icoming
我用的是select()。
可现在的问题是如果套接字集中的一个TCP连接的另一方已经关闭,那么怎样才能把这个套接字从这个调接字集中删掉。
我试了一下FD_CLR这个宏,似乎不能完成上面的要求
请问该怎么做?


你的程序什么样的?你认为不能完成上面要求,理由是?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-6 11:40:55 | 显示全部楼层
fd_set set;
struct timeval timeout
FD_ZERO(&set);
FD_SET(socket1, &set);
FD_SET(socket2, &set);
timeout.tv_sec=10;
timeout.tv_usec=0;
for(int i=0 ; i < 20 ; i++)
{
     select(max(socket1 , socket2) , &set , NULL , NULL , );
     if(FD_ISSET(socket1 , &set))
     {
         int size=recv(socket1 , buffer , size , NULL);//不好意思,recv()的最后一个参数我忘掉了,好像大概是这样。
         if(size == 0)
             FD_CLR(socket1 , &set);
     }
     if(FD_ISSET(socket2 , &set))
     {
         int size=recv(socket2 , buffer , size , NULL);
         if(size == 0)
             FD_CLR(socket2 , &set);
     }
}
这样一旦有一个连接断开,接下来的几次都是从那个断开的连接中返回。我想把这个断开的连接从整个套接字集中删除,可是上面的代码好像有问题,还是每次都在断开的套接字集中返回,而且每次都是返回的都是0。
回复 支持 反对

使用道具 举报

发表于 2005-2-6 12:27:02 | 显示全部楼层
(1) select 的第一个参数应该是 max(socket1 , socket2) + 1
(2) select 的最后一个参数 timeout 你设的是多少?
(3) 检查 select 的返回值,确认是否真的是因为有可读的数据才返回的。
回复 支持 反对

使用道具 举报

发表于 2005-2-6 12:27:45 | 显示全部楼层
看出几个问题
1. select的第一个参数搞错了吧
2. select返回后set应该根据触发的情况改变了,下次循环要重新设置

Post by icoming


  1. fd_set set;
  2. struct timeval timeout
  3. FD_ZERO(&set);
  4. FD_SET(socket1, &set);
  5. FD_SET(socket2, &set);
  6. timeout.tv_sec=10;
  7. timeout.tv_usec=0;
  8. for(int i=0 ; i < 20 ; i++)
  9. {
  10. [color=Blue] /* 在每次循环中重新设置set,怎么设自己看着办了 */
  11.     FD_ZERO(&set);
  12.     FD_SET(socket1, &set);
  13.     FD_SET(socket2, &set);
  14. [/color]
  15.      select(max(socket1 , socket2)[color=Blue] +1[/color], &set , NULL , NULL , );  [color=Blue] /* 忘记加1了吧 */ [/color]
  16.      if(FD_ISSET(socket1 , &set))
  17.      {
  18.          int size=recv(socket1 , buffer , size , NULL);//不好意思,recv()的最后一个参数我忘掉了,好像大概是这样。
  19.          if(size == 0)
  20.              FD_CLR(socket1 , &set);
  21.      }
  22.      if(FD_ISSET(socket2 , &set))
  23.      {
  24.          int size=recv(socket2 , buffer , size , NULL);
  25.          if(size == 0)
  26.              FD_CLR(socket2 , &set);
  27.      }
  28. }
复制代码

这样一旦有一个连接断开,接下来的几次都是从那个断开的连接中返回。我想把这个断开的连接从整个套接字集中删除,可是上面的代码好像有问题,还是每次都在断开的套接字集中返回,而且每次都是返回的都是0。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-6 17:00:06 | 显示全部楼层
谢谢各位了
不过为什么每次循环都要重新设置套接字集呢
select的第一个参数加了1后,结果还是有错误。
每次循环重新设置套接字集后就没有问题了
回复 支持 反对

使用道具 举报

发表于 2005-2-6 20:06:00 | 显示全部楼层
每次调用select后,rdset,wrset,exset都会改变,所以在下一次使用select的之前,必须重新设置rdset,wrset,exset。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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