connect函数设置为非阻塞


前言

网络编程中socket默认都是阻塞模式,在一些高并发或者多线程任务中,阻塞模式会极大影响效率,以connect为例,如果连接网络有问题,或者服务端不能及时响应连接,导致connect函数阻塞(阻塞时间75s),为避免这种情况,在connect前,将socket fd设置为非阻塞,然后将fd交给select监听,当fd状态发生变化,使用getsoktopt判断fd是何种类型,进而判断connect状态。


一、代码

代码如下(示例):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <errno.h>

int main()
{
    int ret =0;
    unsigned long ul = 1;
    struct timeval timeout;
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;
    
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    ioctl(sock,FIONBIO, &ul);
    
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("172.0.0.1");
    serv_addr.sin_port = htons(8700);
    
    fd_set sfd;
    FD_ZERO(&sfd);
    FD_SET(sock, &sfd);
    ret = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if (ret == 0)
    {
        close(sock);
        return 0;
    }
    else if (ret == -1)
    {
        if (errno != EINPROGRESS)
        {
            close(sock);
            return -1;
        }
        
        int count = select(sock+1, NULL, &sfd, NULL, &timeout);
        if (count == 0 || count == -1)
        {
            close(sock);
            return -1;
        }
        if (FD_ISSET(sock, &sfd))
        {
            int err = 0;
            socklen_t len = sizeof(err);
            if (getsockopt(sock,SOL_SOCKET, SO_ERROR, &err, &len) == -1)
            {
                close(sock);
                return -1;
            }
            if (err !=0)
            {
                close(sock);
                return -1;
            }
            ul = 0;
            ioctl(sock,FIONBIO, &ul);
        }
    
    }
    else
    {
        close(sock);
        return -1;
    }
    char buffer[10] = {0};
    read(sock, buffer, sizeof(buffer)-1);
    
    printf("resv : %s\n", buffer);
    close(sock);
}

 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值