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 返回值做检查,才发现这个现象。。

原文地址:https://www.cnblogs.com/hangj/p/7493813.html