本文共 1703 字,大约阅读时间需要 5 分钟。
在之前的博文中, 我们在Windows下玩过带有超时时间的, 本文我们在linux下来玩。 在某次面试中, 还被遇到了这个问题, 有意思。
直接上客户端代码:
#include服务端代码, 我们已经写过多次, 本文就不写了。#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) // 注意输入参数, 带上ip和port{ int sockClient = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr(argv[1]); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(atoi(argv[2])); fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno)); // 返回-1不一定是异常 if (iRet != 0) { if(errno != EINPROGRESS) { printf("connect error:%s\n", strerror(errno)); } else { struct timeval tm = {5, 0}; fd_set wset, rset; FD_ZERO(&wset); FD_ZERO(&rset); FD_SET(sockClient, &wset); FD_SET(sockClient, &rset); int time1 = time(NULL); int n = select(sockClient + 1, &rset, &wset, NULL, &tm); int time2 = time(NULL); printf("time gap is %d\n", time2 - time1); if(n < 0) { printf("select error, n is %d\n", n); } else if(n == 0) { printf("connect time out\n"); } else if (n == 1) { if(FD_ISSET(sockClient, &wset)) { printf("connect ok!\n"); fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); } else { printf("unknow error:%s\n", strerror(errno)); } } else { printf("oh, not care now, n is %d\n", n); } } } printf("I am here!\n"); getchar(); close(sockClient); return 0;}
经测试, 上述程序OK, 用tcpdump抓包, 还能学到不少东西, 比如SYN包重传, RST包等。 有点意思。
转载地址:http://mjwti.baihongyu.com/