免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: jeanlove

[C] 请教,我的select函数的timeval不起作用? [复制链接]

论坛徽章:
0
发表于 2009-05-13 11:27 |显示全部楼层
原帖由 ideawu 于 2009-5-13 11:05 发表

正是这样的.

不能随便地得出这种推论.

对于你的问题的解决方法: 检测到连接失败, 重新connect.


嗯,也就是说我的这种情况得重连,而不是用select。
kinwin 该用户已被删除
发表于 2009-05-13 11:50 |显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
发表于 2009-05-13 11:56 |显示全部楼层
原帖由 urapple 于 2009-5-13 11:42 发表
楼主大大
select的作用是检查描述符的状态,是否有数据过来,比如
要查读描述符,那就检查读描述符的状态,有数据来,就会返回,否则,一直等待,知道你设定的超时时间退出。
而你上面的connect的问题,不是 ...


谢谢,越说越明白了。

论坛徽章:
0
发表于 2009-05-13 11:56 |显示全部楼层
原帖由 kinwin 于 2009-5-13 11:50 发表

如果只检测读端的话,会一直等待到返回错误


重连+定时。


谢谢,很好的纠正。

论坛徽章:
0
发表于 2009-05-13 13:47 |显示全部楼层

回复 #9 jeanlove 的帖子

timeval参数应该在每次循环的时候重置,不然不会起作用

论坛徽章:
0
发表于 2009-05-13 14:32 |显示全部楼层
我用 python 写了个小程序在本地听,但不 accept,然后用你的程序去连(改了连接地址),结果是 timeout



  1. #!/usr/bin/python

  2. import socket

  3. ss=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. ss.bind(('127.0.0.1',8080))
  5. ss.listen(8080)
  6. while True:
  7.         None;
复制代码


  1. #include<sys/types.h>
  2. #include<sys/socket.h>
  3. #include<arpa/inet.h>
  4. #include<fcntl.h>
  5. #include<stdio.h>
  6. #include<errno.h>
  7. #include<string.h>
  8. #include<sys/select.h>
  9. int
  10. main (void)
  11. {
  12.   int s, r, ret, len, error;
  13.   char buf[20];
  14.   struct sockaddr_in sock;
  15.   fd_set rset, wset;
  16.   struct timeval tv;
  17.   tv.tv_sec = 10;
  18.   s = socket (AF_INET, SOCK_STREAM, 0);
  19.   if (-1 == s)
  20.     {
  21.       printf ("socket() failed\n");
  22.       return 1;
  23.     }
  24.   if (0 >
  25.         fcntl (s, F_SETFL, fcntl (s, F_GETFL, 0) | /*O_NDELAY */ O_NONBLOCK))
  26.     {                                /*非阻塞 */
  27.       printf ("fcntl failed\n");
  28.       return 1;
  29.     }
  30.   sock.sin_family = PF_INET;
  31.   sock.sin_port = htons (8080);
  32.   sock.sin_addr.s_addr =inet_addr("127.0.0.1");
  33.   if (-1 ==
  34.         (ret =
  35.          connect (s, (struct sockaddr *) &sock, sizeof (struct sockaddr_in))))
  36.     {
  37.       if (EINPROGRESS != errno)
  38.         {                        /*if not fcntl->O_NDELAY, fall here */
  39.           printf ("connect() failed:%s\n", strerror (errno));
  40.           return 1;
  41.         }
  42.     }
  43.   if (ret == 0)
  44.     {
  45.       printf ("connection ok at once\n");
  46.       close (s);
  47.       return 0;
  48.     }
  49.   FD_ZERO (&rset);
  50.   FD_SET (s, &rset);
  51.   wset = rset;
  52.   if (-1 == (ret = select (s + 1, &rset, &wset, NULL, &tv)))
  53.     {                                /*设置timeval时间参数 */
  54.       close (s);
  55.       printf ("select error\n");
  56.       return 1;
  57.     }
  58.   if (0 == ret)
  59.     {
  60.       close (s);
  61.       printf ("timeout\n");
  62.       return 1;
  63.     }
  64.   if ( /*FD_ISSET(s,&rset) */ FD_ISSET (s, &wset))
  65.     {
  66.       len = sizeof (error);
  67.       errno = 0;
  68.       if (0 >
  69.            (ret =
  70.             getsockopt (s, SOL_SOCKET, SO_ERROR, (void *) &error, &len)))
  71.         {
  72.           close (s);
  73.           printf ("getsockopt error:%s\n", strerror (errno));
  74.           return 1;
  75.         }
  76.       if (error != 0)
  77.         {
  78.           printf ("getsockopt set error:%s\n", strerror (errno));
  79.           close (s);
  80.           return 1;
  81.         }
  82.       printf ("getsockopt success\n");
  83.     }
  84.   else
  85.     {
  86.       close (s);
  87.       printf ("FD_ISSET error\n");
  88.       return 1;
  89.     }
  90.   if (-1 == (ret = read (s, buf, sizeof (buf))))
  91.     {
  92.       printf ("read() failed\n");
  93.       return 1;
  94.     }                                /*如果连接成功就从server读取点东西 */
  95.   printf ("ret=%d\n", ret);
  96.   buf[ret - 1] = '\0';
  97.   printf ("read:%s\n", buf);
  98.   close (s);
  99.   return 0;
  100. }
复制代码

[ 本帖最后由 win_hate 于 2009-5-13 15:06 编辑 ]

论坛徽章:
0
发表于 2009-05-13 14:39 |显示全部楼层
原帖由 win_hate 于 2009-5-13 14:32 发表
我用 python 写了个小程序在本地听,但不 accept,然后用你的程序去连(改了连接地址),结果是 timeout



#!/usr/bin/python

import socket

ss=socket.socket(socket.AF_INET, socket.SOCK_STREAM) ...

嗯,也就是说必须存在服务器端已经listen了,客户端才能非阻塞的connect并且能用select定时。

论坛徽章:
0
发表于 2009-05-13 16:59 |显示全部楼层
最初用你的地址 INADDR_ANY,会报地址错误

如果用合法地址,对方没有侦听,报连接被拒绝

如果对方在听了,但没有向你发送消息,select 认为文件描述符是不可读的

如果三路握手完成,则 select 认为文件描述符是可写的。

你写一个服务去听,客户在 select 时把 *wset 参数 设 NULL  就可以观察到 timeout

论坛徽章:
0
发表于 2009-05-13 18:05 |显示全部楼层
原帖由 win_hate 于 2009-5-13 16:59 发表
最初用你的地址 INADDR_ANY,会报地址错误

如果用合法地址,对方没有侦听,报连接被拒绝

如果对方在听了,但没有向你发送消息,select 认为文件描述符是不可读的

如果三路握手完成,则 select 认为文件 ...

我试试啊。

论坛徽章:
0
发表于 2009-05-15 16:07 |显示全部楼层
学习备用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP