linux下socket的connect超时

代码的流程是这样的
1 建立一个socket
2 设置socket为非阻塞
3 connect
4 把socket放到一个fd_set中
5 select 这个socket,监视可写事件
6 判断是否超时或者连接成功
   
代码如下---------------------------------------------------------------------
struct sockaddr_in servAddr;
servAddr.sin_port = htons(port);
servAddr.sin_family = AF_INET;
inet_aton(servIp,&servAddr.sin_addr);
//设置socket为非阻塞
unsigned long ul = 1;
int rm = ioctl(this->m_socket,FIONBIO,&ul);
if(rm == -1)
{
 //ioctl failed
 return -1;
}
if(connect(this->m_socket,(sockaddr*)&servAddr,sizeof(sockaddr)) == 0)
{
 //connect success
 return 0;
}

if(errno != EINPROGRESS)
{
 return -1;
}
log_debug("%s",strerror(errno));
//检测socket是否可写
fd_set writeSet,readSet;
FD_ZERO(&writeSet);
FD_SET(this->m_socket,&writeSet);
int num = select(this->m_socket+1, NULL, &writeSet,NULL,tv);
if(num > 0)
{
 if(FD_ISSET(this->m_socket,&writeSet))
 {
  //设置socket为阻塞
  ul = 0;
  ioctl(this->m_socket,FIONBIO,&ul);
  return 0;
 }
}

首先说一下这段代码的执行结果:当连接一个并不存在的socket时,select总是返回连接成功
 
按照这个流程,这段代码的依据就是当非阻塞时,connect立刻返回-1,同时errno设置为EINPROGRESS。然后再检测socket是否可写,如果可写了,说明socket已经建立的连接,这个时候select的会在write fd_set中把socektfd置位,同时返回,这个时候判断select的返回值和用FD_ISSET宏来判断是否socketfd是否已经被置位来判断是否连接成功。注意:所有的这一切都是建立在 “如果一个socket建立了连接,那么这个socket是可写的”,这看起来没有错,但是关键是,如果连接不成功,select是否会判断socket为可写的呢?我们知道,当连接被关闭时,select仍然判断socket是可读的。难道即使socket连接不成功,select仍然返回
可写吗?经过试验,真的是这样的。所以,上面的代码如果在异常情况下仍然正常工作,在select返回时须作如下修改:
if(FD_ISSET(this->m_socket,&writeSet))
{
 int error = 0;
 int errLen = sizeof(error);
 if(getsockopt(this->m_socket,SOL_SOCKET,SO_ERROR,&error,(socklen_t*)&errLen) < 0)
 {
  return -1;
 }
 if(error != 0)
 {//当error等于0的时候才说明连接成功
  return -1;
 }
 //设置socket为阻塞
 ul = 0;
 ioctl(this->m_socket,FIONBIO,&ul);
 return 0;
}

//以上的代码中的思想我正在用,但真的没起到连接超时的效果,一旦连接不成功还是回立即返回的.还有socket在阻塞的情况下,connect()也没有阻塞,也是立即返回的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值