zoukankan      html  css  js  c++  java
  • 由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?

    一般情况下,我们像下面代码中所示的这样使用非阻塞connect:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <arpa/inet.h>
    #include <sys/epoll.h>
    #include <errno.h>
    
    #define EPOLL_MAXEVENTS 64
    
    int main(int argc, char *argv[])
    {
        int fd, epfd, flags, status, ret, nevents, i, slen;
        struct sockaddr_in addr;
        struct in_addr remote_ip;
        struct epoll_event ev, events[EPOLL_MAXEVENTS];;
    
    
        if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {
            perror("socket failed");
            return -1;
        }
    
        status = 1;
        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int))) {
            perror("setsockopt failed");
            return -1;
        }
    
       flags = fcntl(fd, F_GETFL, 0);
        fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        addr.sin_port = 9999;
        if (inet_pton(AF_INET, "10.232.129.43", &addr.sin_addr) <= 0) {
            perror("inet_pton error");
            return -1;
        }
    
    
    
        ret = connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
        if (ret == 0) {
            printf("non-blocking connect success. connect complete immediately");
            close(fd);
            return -1;
        }
    
        if (ret < 0 && errno != EINPROGRESS) {
            perror("connect error!");
            return -1;
        }
    
    
        epfd = epoll_create(EPOLL_MAXEVENTS);
     ev.events = EPOLLOUT;
        ev.data.fd = fd;
        if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1 ) {
            perror("epoll_ctl error");
            goto finish;
        }
        printf("add connect fd into epoll");
    
        memset(events, 0, sizeof(events));
    
        for (;;) {
    
            nevents = epoll_wait(epfd, events, EPOLL_MAXEVENTS, -1);
    
            if (nevents < 0) {
                perror("epoll_wait failed");
                goto finish;
            }
    
            for (i = 0; i < nevents; i++) {
    
                if (events[i].data.fd == fd) {
    
                    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen)
                        < 0)
                    {
                        perror("getsockopt error!");
                        goto finish;
                    }
                    if (status != 0) {
                        perror("connect error!");
                        goto finish;
                    }
    
                    printf("non-blocking connect success!");
    
                    if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) == -1 ) {
                        perror("epoll_ctl error");
                        return 0;
                    }
    
                    /* DO write... */
                }
            }
        }
    
     finish:
        close(fd);
        close(epfd);
    
        return 0;
    }
    

      在上面的代码中需要注意几点:

    1,什么时候connect返回成功?

       三次握手中的client如果收到server对SYN的ACK,connect就会返回。

    2,非阻塞的connect成功返回后,用getsockopt获得的SO_ERROR码还会使EINPROGRESS吗?

       不会。除非是epoll设置的超时时间到达,否则epoll_wait返回fd后,表明fd已经可写,connect已经建立成功。此时如果getsockopt获取到的SO_ERROR 状态码是status表明connect已失败,不可能再是EINPROGRESS。

  • 相关阅读:
    asp.net将word转成HTML
    asp.net 控件位置form验证
    javascript 正则表达式
    .net framework处理xml
    XMLHTTP与XMLDOC使用介绍(上)
    一个女程序员的征婚信息的select语句
    解决连接MySql4.0数据库出现的"character_set_results"问题
    javascript与cs代码互访
    杜绝<script src="js/tool.js" type="text/javascript"/>这样写的习惯
    总结:常用的正则表达式集合
  • 原文地址:https://www.cnblogs.com/cobbliu/p/3764603.html
Copyright © 2011-2022 走看看