Linux 网络编程一步一步学(四)-设置非阻塞方式
1 #include <stdio.h> 2 #include <string.h> 3 #include <errno.h> 4 #include <sys/socket.h> 5 #include <resolv.h> 6 #include <stdlib.h> 7 #include <netinet/in.h> 8 #include <arpa/inet.h> 9 #include <unistd.h> 10 #include <fcntl.h> 11 #define MAXBUF 10 12 int main(int argc, char **argv) - 13 { | 14 int sockfd, ret, rcvtm = 0; | 15 struct sockaddr_in dest, mine; | 16 char buffer[MAXBUF + 1]; - 17 if (argc != 5) { 2 18 printf("参数格式错误!正确用法如下:\n\t\t%s 对方IP 地址 对方端口 本机IP 地址 本机端口\n\t比如:\t%s 127.0.0.1 82 0\n此程序用来以本机固定的端口从某个 IP 地址的服务器某个端口接收最多MAXBUF 个字节的消息",argv[0], argv[0]); 2 19 exit(0); 2 20 } | 21 /* 创建一个 socket 用于 tcp 通信 */ | 22 sockfd = socket(AF_INET, SOCK_STREAM, 0); | 23 /* 初始化服务器端(对方)的地址和端口信息 */ | 24 bzero(&dest, sizeof(dest)); | 25 dest.sin_family = AF_INET; | 26 dest.sin_port = htons(atoi(argv[2])); - 27 if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) { 2 28 perror(argv[1]); 2 29 exit(errno); 2 30 } | 31 /* 初始化自己的地址和端口信息 */ | 32 bzero(&mine, sizeof(mine)); | 33 mine.sin_family = AF_INET; | 34 mine.sin_port = htons(atoi(argv[4])); - 35 if (inet_aton(argv[3], (struct in_addr *) &mine.sin_addr.s_addr) == 0) { 2 36 perror(argv[3]); 2 37 exit(errno); 2 38 } | 39 /* 把自己的 IP 地址信息和端口与 socket 绑定 */ - 40 if (bind(sockfd, (struct sockaddr *) &mine, sizeof(struct sockaddr)) == -1) { 2 41 perror(argv[3]); 2 42 exit(errno); 2 43 } | 44 /* 连接服务器 */ - 45 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { 2 46 perror("Connect "); 2 47 exit(errno); 2 48 } | 49 /* 设置 socket 属性为非阻塞方式 */ - 50 if(fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { 2 51 perror("fcntl"); 2 52 exit(errno); 2 53 } | 54 /* 接收对方发过来的消息,每次最多接收 MAXBUF 个字节,直到把对方发过来的所有消息接收完毕为止 */ - 55 do { 2 56 _retry: 2 57 bzero(buffer, MAXBUF + 1); 2 58 ret = recv(sockfd, buffer, MAXBUF, 0); 2 59 if(ret > 0) 2 60 printf("读到%d个字节,它们是:'%s'\n", ret, buffer); - 61 if(ret < 0) { 3 62 if(errno == EAGAIN) { 3 63 if(rcvtm) 3 64 break; 3 65 else { 3 66 printf("数据还未到达!\n"); 3 67 usleep(100000); 3 68 goto _retry; 3 69 }; 3 70 }; 3 71 printf("接收出错了!\n"); 3 72 perror("recv"); 3 73 } 2 74 rcvtm++; 2 75 }while(ret==MAXBUF); | 76 /* 关闭连接 */ | 77 close(sockfd); | 78 return 0; | 79 } 80