LinuxSir.cn,穿越时空的Linuxsir!

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

网络编成connect()遇到的问题

[复制链接]
发表于 2006-6-3 19:26:46 | 显示全部楼层 |阅读模式
问题:在阻塞模式下,connect()函数被信号阻断时,该如何处理?

这时connect返回-1,并且设置errno = EINTR。那么,tcp的三次握手还在继续进行吗?
发表于 2006-6-4 21:38:46 | 显示全部楼层
EINTR的错误类型不应该被视为真正的错误,它一般是由本地的某些其它操作引起的,应该重试直到成功或者发生真正的错误(其它的错误)为止
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-6-6 21:35:12 | 显示全部楼层
怎样重试呢?不能再调用connect()了.否则出错EADDRINUSE。
帮帮忙,给个代码?谢谢!
回复 支持 反对

使用道具 举报

发表于 2006-6-6 23:47:53 | 显示全部楼层

  1. while (((t = connect()) == -1) && (errno == EINTR)) ;
  2. if (t == -1) {
  3.   /* error */
  4. }
  5. /* ok */
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-6-6 23:53:55 | 显示全部楼层
按理说如果错误是 EINTR, 那么握手还未完成, 应该进行重试

如果导致 EADDRINUSE 错误, 那么楼主确信它是由重试 connect 导致的吗? 还是由错误的参数导致的? 楼主可以用 strerror(errno) 来查看一下它的错误原因.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-6-7 11:13:19 | 显示全部楼层
3ks very much.

请问DODO: 以上的代码你自己用过不?可以直接再调用CONNECT()?不会返回错误?
我得试试,3KS AGAIN.
回复 支持 反对

使用道具 举报

发表于 2006-6-7 22:28:53 | 显示全部楼层
我自己都是这么写的, 不过也许是我的 connect 一般没有发生过失败, 所以可能会有潜在的问题我没有发现

这里附上 APUE 2ed 中的一段例子

  1. #include "apue.h"
  2. #include <sys/socket.h>

  3. #define MAXSLEEP 128

  4. int
  5. connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
  6. {
  7.     int nsec;
  8.    
  9.     /*
  10.      * Try to connect with exponential backoff.
  11.      */
  12.     for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
  13.         if (connect(sockfd, addr, alen) == 0) {
  14.             /*
  15.              * Connection accepted.
  16.              */
  17.             return(0);
  18.         }

  19.         /*
  20.          * Delay before trying again.
  21.          */
  22.         if (nsec <= MAXSLEEP/2)
  23.             sleep(nsec);
  24.     }
  25.     return(-1);
  26. }

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-6-8 22:18:20 | 显示全部楼层
我试了当connect()被信号打断的时候,再立刻调用connect()会返回EALREADY(我在FreeBSD6.0系统下)。
你上面的代码,应该CONNECT()不会返回0。
回复 支持 反对

使用道具 举报

发表于 2006-6-8 23:27:08 | 显示全部楼层
下面是 man connect 中提供的关于 EALREADY 的说明
  1. EALREADY
  2.        The socket is non-blocking and a previous connection attempt has
  3.        not yet been completed.
复制代码

或者按照 APUE 中的代码, 每次 connect 失败后 sleep 一定时间吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-6-9 07:52:45 | 显示全部楼层
我看的资料上也是这样说的。可是我试验的结果是返回EALREADY(在阻塞模式下,connect()被磨一个信号中断时(我是人工用EALRAM信号))。

不理解了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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