linux下socket connect非阻塞与阻塞

本文介绍如何使用fcntl方法在Linux环境下设置socket为阻塞或非阻塞模式,并提供了一个利用select进行非阻塞connect操作的例子。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将一个socket 设置成阻塞模式和非阻塞模式,使用fcntl方法,
设置成非阻塞模式:
      flags = fcntl(sockfd, F_GETFL, 0);                        //获取文件的flags值。
      fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);   //设置成非阻塞模式;
设置成阻塞模式:
     flags  = fcntl(sockfd,F_GETFL,0);                          //获取文件的flags值。
     fcntl(sockfd,F_SETFL,flags&~O_NONBLOCK);    //设置成阻塞模式; 

在将socket设置成非阻塞模式后,每次的对于sockfd 的操作都是非阻塞的;
非阻塞模式下:
connect   
       =0   当返回0时,表示立即创建了socket链接,
       <0   当返回-1时,需要判断errno是否是EINPROGRESS(表示当前进程正在处理),否则失败。

select监听connect是否成功的例子,注意getsockopt验证,因为三次握手的第三个ACK有可能会丢失,但是客户端认为链接已经建立:

struct sockaddr_in serv_addr;

int sockfd=socket(AF_INET, SOCK_STREAM, 0);

int ret = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr);
if(ret == 0){}/ /建立链接成功
else if(ret < 0 && errno == EINPROGRESS)          //errno == EINPROGRESS表示正在建立链接
{
     // 等待连接完成,errno == EINPROGRESS表示正在建立链接
     fd_set set;
     FD_ZERO(&set);
     FD_SET(sockfd,&set); 
     struct timeval timeo;
     timeo.tv_sec = 0; 
     timeo.tv_usec = 100 * 1000; // 超时时间100ms
     int retval = select(sockfd+ 1, NULL, &set, NULL, &timeo);           //事件监听
     if(retval <= 0)   { } //建立链接错误或超时 close(sockfd)
    else
     {
           int error = 0;
           socklen_t len = sizeof(error);
           if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error != 0)
           {
                  //建立链接失败close(sockfd)
           }
           else
            {
                  //建立链接成功
            }
     }
}
else{ }  //出现错误 close(sockfd)








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值