1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 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\n", 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\n", str);41 //return -1; // 注释掉这里,后面 select 返回 142 }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\n", strerror(err));61 }62 }63 64 }65 66 return 0;67 }
select 一个 "connection refused" 的 socket, socket 居然状态可写。。
原代码用 select 检查 socket 的可写状态来判断连接是否成功,IOS 版本的代码中没有对 connect 返回值做检查,才发现这个现象。。