C 套接字连接结束,此时正在对非阻塞套接字执行操作

C 套接字连接结束,此时正在对非阻塞套接字执行操作,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,我在使用connect()API连接到目标IP时遇到问题。connect()API返回一个-1和一个errno作为正在进行的操作 。我是否在建立连接之前过早检查返回代码?请参阅以下代码段: struct sockaddr_in servAddr; servAddr.sin_family = AF_INET; servAddr.sin_port = htons(9190); const char * remoteIp = 10.1

我在使用connect()API连接到目标IP时遇到问题。connect()API返回一个
-1
和一个errno作为正在进行的
操作

。我是否在建立连接之前过早检查返回代码?请参阅以下代码段:

struct sockaddr_in      servAddr;
        servAddr.sin_family = AF_INET;
            servAddr.sin_port = htons(9190); 
        const char * remoteIp = 10.10.20.86;
            rc = inet_pton(AF_INET,remoteIp, &servAddr.sin_addr);
            if (rc == -1 || errno == EAFNOSUPPORT)
            {
                return 0;
            }
            rc = connect(fd, (sockaddr*)&servAddr, sizeof(servAddr));
         if ( rc < 0) // this is where it fails. rc is -1.
                   {
                        log("connect failure with [%s]",strerror(errno));
                        print_sock_connect_error();
                   }
servAddr中的结构sockaddr\u; servAddr.sin_family=AF_INET; servAddr.sinu port=htons(9190); 常量字符*remoteIp=10.10.20.86; rc=inet\u pton(AF\u inet、remoteIp和servAddr.sin\u addr); 如果(rc==-1 | | errno==EAFNOSUPPORT) { 返回0; } rc=connect(fd,(sockaddr*)&servAddr,sizeof(servAddr)); if(rc<0)//这就是它失败的地方。rc为-1。 { 日志(“与[%s]的连接失败”,strerror(errno)); 打印_sock_connect_error(); } 我这里有两个问题:

  • 目标IP和端口
    10.10.20.86:9190
    正在等待连接,一旦收到连接,就会将ack发送回源。我在pcap中看到tcp已建立—ACK、SYN/ACK和ACK to destination—但仍然无法理解它返回
    -1
    时出错的原因。那么,在连接建立完成之前,我是否要检查rc
    sysctl net.ipv4.tcp\u syn\u retries
    设置为6
  • 上面的代码有什么问题吗
  • 我是否在连接建立完成之前检查rc

    是的,你是。连接建立过程中的TCP乒乓并不是必须完成的全部工作

    上面的代码有什么问题吗

    嗯,是的,无论是它处理
    EINPROGRESS
    案例的方式,还是使用非阻塞套接字进行连接

    connect()
    的Linux:

    EINPROGRESS

    套接字是非阻塞的,无法连接 立即完成。可以选择(2)或轮询(2) 通过选择要写入的套接字来完成。之后 选择(2)表示可写性,使用getsockopt(2)读取 SO_错误选项在SOL_套接字级别确定 connect()已成功完成(因此错误为零)或 未成功(因此,错误是常见的错误代码之一) 此处列出,解释失败的原因)

  • 10.10.20.86:9190正在等待连接,一旦收到连接,它将ack发送回源。我在pcap中看到tcp已建立—ACK、SYN/ACK和ACK to destination—但仍然无法理解它返回-1并出错的原因。那么,在连接建立完成之前,我是否要检查rc
  • 你当然是。您将立即检查它
    connect()
    返回。由于您已将插座置于非阻塞模式,因此三路有线握手不可能在那时完成

    sysctl net.ipv4.tcp_syn_retries设置为6

    无关紧要

  • 上面的代码有什么问题吗
  • 只是它没有意义

    • 如果您希望在
      connect()
      返回之前连接完成或失败,请不要使用非阻塞模式

    • 如果要使用非阻塞模式,则必须使用
      select()
      告诉您连接尝试何时完成。选择此选项可使套接字变为可写。(这并不一定意味着它已成为可写的:它意味着连接尝试已完成,结果可以通过
      getsockopt()/SO\u ERROR
      发现)


    请不要用标签发送垃圾邮件。即使这个问题可能适用于C和C++,只使用你实际编程的语言的标签,因为这会影响可能的解决方案。在一个不相关的注释中,你检查错误的条件是有缺陷的。如果有错误,或者如果没有错误,但是
    errno
    恰好是
    EAFNOSUPPORT
    ,则返回
    0
    。如果没有错误(即,
    inet\u pton
    不返回
    -1
    ),则
    errno
    的值不确定且未知。那就别查了。