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   
原文地址:https://www.cnblogs.com/liqiu/p/2981240.html