• select 的问题


     1 #include <errno.h>
     2 #include <string.h>
     3 #include <fcntl.h>
     4 #include <sys/socket.h>
     5 #include <sys/types.h>
     6 #include <sys/select.h>
     7 #include <netinet/tcp.h>
     8 #include <netinet/ip.h>
     9 #include <arpa/inet.h>
    10 #include <unistd.h>
    11 #include <stdio.h>
    12 
    13 int main(int argc, const char * argv[]) {
    14     int sock = socket(PF_INET, SOCK_STREAM, 0);
    15     if(sock == -1){
    16         const char* str = strerror(errno);
    17         printf("socket: %s
    ", str);
    18         return -1;
    19     }
    20     
    21     int flags = fcntl(sock, F_GETFD, 0);
    22     flags |= O_NONBLOCK;
    23     fcntl(sock, F_SETFD, flags);
    24     
    25     char ch = 1;
    26     setsockopt(sock, IPPROTO_TP, TCP_NODELAY, &ch, sizeof(ch));
    27     int value = 1;
    28     setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));
    29     
    30     struct sockaddr_in addr = {0};
    31     addr.sin_family = AF_INET;
    32     addr.sin_port = htons(8000);
    33     addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    34     
    35     int ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
    36     if(ret){
    37         int err = errno;
    38         if(err != EINPROGRESS && err != EWOULDBLOCK){
    39             const char* str = strerror(errno);
    40             printf("connect: %s
    ", str);
    41             //return -1;    // 注释掉这里,后面 select 返回 1
    42         }
    43         
    44         int nfds = 0;
    45         fd_set wset;
    46         FD_ZERO(&wset);
    47         FD_SET(sock, &wset);
    48         nfds = sock + 1;
    49         
    50         struct timeval timeout;
    51         timeout.tv_sec = 1;
    52         timeout.tv_usec = 0;
    53         int n = select(nfds, 0, &wset, 0, &timeout);
    54         if(n > 0){
    55             struct sockaddr in = {0};
    56             socklen_t len = sizeof(in);
    57             int e = getpeername(sock, &in, &len);
    58             if(e){
    59                 int err = errno;
    60                 printf("getpeername: %s
    ", strerror(err));
    61             }
    62         }
    63         
    64     }
    65     
    66     return 0;
    67 }

    select 一个 "connection refused" 的 socket, socket 居然状态可写。。

    原代码用 select 检查 socket 的可写状态来判断连接是否成功,IOS 版本的代码中没有对 connect 返回值做检查,才发现这个现象。。

  • 相关阅读:
    洛谷 2574 XOR的艺术
    洛谷 1774 最接近神的人
    洛谷 3398 仓鼠找sugar 【模板】判断树上两链有交
    洛谷 2440 木材加工
    洛谷 1824 进击的奶牛
    洛谷 1873 砍树
    洛谷 1577 切绳子
    51nod1485 字母排序
    51nod1055 最长等差数列
    51nod1128 正整数分组V2
  • 原文地址:https://www.cnblogs.com/hangj/p/7493813.html
Copyright © 2020-2023  润新知