由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?「建议收藏」

由select/epoll返回的非阻塞connect还会是EINPROGRESS状态吗?「建议收藏」一般情况下,我们像下面代码中所示的这样使用非阻塞connect:#include#include#include#include#include#include#include#incl

大家好,又见面了,我是你们的朋友全栈君。

一般情况下,我们像下面代码中所示的这样使用非阻塞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。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154718.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jvm基础_java实现栈四个方法

    jvm基础_java实现栈四个方法JVM进阶(一)——初识JAVA栈  若想使自己编写的Java程序高效运行,以及进行正确、高效的异常诊断,JVM是不得不谈的一个话题。本”JVM进阶“专栏大部分内容均来源于经典书籍《深入理解Java虚拟机》。  下面言归正传,本文重点从虚拟机内存模型(运行时数据区域)入手。先看图:  这是一张比较官方的虚拟机模型图,今天讲的就是虚线框中栈的部分。  栈是我们最常用的内存区域。它主

    2022年9月6日
    3
  • handlersocket原理和性能测试[通俗易懂]

    handlersocket原理和性能测试[通俗易懂]1.handlersocket原理很久以前做的测试了,今天只是为了留个存底的地方,所以拿上来,有很多不严谨的地方望大家多多包涵,也可以留言更正我的错误,谢谢!都说handlersocket速度不是

    2022年7月2日
    17
  • 高德地图-设置点标注的文本标签「建议收藏」

    高德地图-设置点标注的文本标签「建议收藏」1、问题背景   高德地图中,设置选中位置,并自定义图标和文字提示2、实现源码 高德地图-设置点标注的文本标签 varmap=newAMap.Map(“container”,{ resizeEnable:true, center:[115.397428,41.90

    2022年5月22日
    170
  • pycharm2021年激活码刚出_最新在线免费激活

    (pycharm2021年激活码刚出)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~S3…

    2022年3月26日
    40
  • 向量的内,外积及其几何含义讲解_两向量外积的几何意义

    向量的内,外积及其几何含义讲解_两向量外积的几何意义一、向量的内积(点乘)定义概括地说,向量的内积(点乘/数量积)。对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,如下所示,对于向量a和向量b:a和b的点积公式为:这里要求一维向量a和向量b的行列数相同。注意:点乘的结果是一个标量(数量而不是向量)定义:两个向量a与b的内积为a·b=|a||b|cos∠(a,b),特别地,0·a=a·0…

    2022年9月24日
    0
  • fastjson -String转JSONArray,JSONArray转List[通俗易懂]

    fastjson -String转JSONArray,JSONArray转List[通俗易懂]String转JsonArrayStringreview=”[{“name”:”人员A”,”review_grades”:{“name”:”优秀”,”parent”:”-1″,”key”:”1″},”remark”:”XXX今年XXX获得优秀党员称号”},{“name”:”人员B”,”review_grades”:{“name”:”合格”,”parent”:”-1″,”key”:”2″},”remark”:”表现良好”},{“name”:”人员C”,”review_grades”:{“name”:”

    2022年6月20日
    81

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号