• Linux C/C++ UDP Socket通信实例


    环境:Linux

    语言:C/C++

    通信方式:UDP

    服务器端的步骤如下:

    1. socket:      建立一个socket

    2. bind:          将这个socket绑定在某个端口上(AF_INET)

    3. recvfrom:  如果没有客户端发起请求,则会阻塞在这个函数里

    4. close:        通信完成后关闭socket

    客户端的步骤如下:

    1. socket:      建立一个socket

    2. sendto:     向服务器的某个端口发起请求(AF_INET)

    3. close:        通信完成后关闭socket

    基于UDP的接收和发送函数

    int recvfrom(int sockfd, void * buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen);

    int sendto(int sockfd, const void * buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen);

    UDP套接字不会保持连接状态,每次传输数据都要添加目标地址信息,这相当于在邮寄包裹前填写收件人地址。

    recvfrom用于接收数据,sendto用于发送数据

    recvfrom:

    • sockfd:用于接收UDP数据的套接字;
    • buf:保存接收数据的缓冲区地址;
    • len:可接收的最大字节数(不能超过buf缓冲区的大小);
    • flags:可选项参数,若没有可传递0;
    • src_addr:存有发送端地址信息的sockaddr结构体变量的地址;
    • addrlen:保存参数 src_addr的结构体变量长度的变量地址值。

    sendto:

    • sockfd:用于传输UDP数据的套接字;
    • buf:保存待传输数据的缓冲区地址;
    • len:带传输数据的长度(以字节计);
    • flags:可选项参数,若没有可传递0;
    • dest_addr:存有目标地址信息的 sockaddr 结构体变量的地址;
    • addrlen:传递给参数 dest_addr的地址值结构体变量的长度。

    Server.cpp

     1 #include <stdio.h>   
     2 #include <sys/types.h>   
     3 #include <sys/socket.h>   
     4 #include <netinet/in.h>   
     5 #include <unistd.h>   
     6 #include <errno.h>   
     7 #include <string.h>   
     8 #include <stdlib.h>   
     9   
    10 #define SERV_PORT   8000   
    11   
    12 int main()  
    13 {  
    14   /* sock_fd --- socket文件描述符 创建udp套接字*/  
    15   int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    16   if(sock_fd < 0)  
    17   {  
    18     perror("socket");  
    19     exit(1);  
    20   }  
    21   
    22   /* 将套接字和IP、端口绑定 */  
    23   struct sockaddr_in addr_serv;  
    24   int len;  
    25   memset(&addr_serv, 0, sizeof(struct sockaddr_in));  //每个字节都用0填充
    26   addr_serv.sin_family = AF_INET;              //使用IPV4地址
    27   addr_serv.sin_port = htons(SERV_PORT);          //端口
    28   /* INADDR_ANY表示不管是哪个网卡接收到数据,只要目的端口是SERV_PORT,就会被该应用程序接收到 */  
    29   addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);  //自动获取IP地址
    30   len = sizeof(addr_serv);  
    31     
    32   /* 绑定socket */  
    33   if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)  
    34   {  
    35     perror("bind error:");  
    36     exit(1);  
    37   }  
    38   
    39     
    40   int recv_num;  
    41   int send_num;  
    42   char send_buf[20] = "i am server!";  
    43   char recv_buf[20];  
    44   struct sockaddr_in addr_client;  
    45   
    46   while(1)  
    47   {  
    48     printf("server wait:
    ");  
    49       
    50     recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);  
    51       
    52     if(recv_num < 0)  
    53     {  
    54       perror("recvfrom error:");  
    55       exit(1);  
    56     }  
    57   
    58     recv_buf[recv_num] = '';  
    59     printf("server receive %d bytes: %s
    ", recv_num, recv_buf);  
    60   
    61     send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);  
    62       
    63     if(send_num < 0)  
    64     {  
    65       perror("sendto error:");  
    66       exit(1);  
    67     }  
    68   }  
    69     
    70   close(sock_fd);  
    71     
    72   return 0;  
    73 }

    Client.cpp

     1 #include <stdio.h>   
     2 #include <string.h>   
     3 #include <errno.h>   
     4 #include <stdlib.h>   
     5 #include <unistd.h>   
     6 #include <sys/types.h>   
     7 #include <sys/socket.h>   
     8 #include <netinet/in.h>   
     9 #include <arpa/inet.h>   
    10    
    11   
    12 #define DEST_PORT 8000   
    13 #define DSET_IP_ADDRESS  "127.0.0.1"   
    14    
    15   
    16 int main()  
    17 {  
    18   /* socket文件描述符 */  
    19   int sock_fd;  
    20   
    21   /* 建立udp socket */  
    22   sock_fd = socket(AF_INET, SOCK_DGRAM, 0);  
    23   if(sock_fd < 0)  
    24   {  
    25     perror("socket");  
    26     exit(1);  
    27   }  
    28     
    29   /* 设置address */  
    30   struct sockaddr_in addr_serv;  
    31   int len;  
    32   memset(&addr_serv, 0, sizeof(addr_serv));  
    33   addr_serv.sin_family = AF_INET;  
    34   addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);  
    35   addr_serv.sin_port = htons(DEST_PORT);  
    36   len = sizeof(addr_serv);  
    37   
    38     
    39   int send_num;  
    40   int recv_num;  
    41   char send_buf[20] = "hey, who are you?";  
    42   char recv_buf[20];  
    43       
    44   printf("client send: %s
    ", send_buf);  
    45     
    46   send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);  
    47     
    48   if(send_num < 0)  
    49   {  
    50     perror("sendto error:");  
    51     exit(1);  
    52   }  
    53     
    54   recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);  
    55     
    56   if(recv_num < 0)  
    57   {  
    58     perror("recvfrom error:");  
    59     exit(1);  
    60   }  
    61     
    62   recv_buf[recv_num] = '';  
    63   printf("client receive %d bytes: %s
    ", recv_num, recv_buf);  
    64     
    65   close(sock_fd);  
    66     
    67   return 0;  
    68 }

     程序运行截图:

    client向服务器发送了“hey, who are you?”的字符串,server返回"i am server!"的字符串。

    参考链接:

    https://blog.csdn.net/imxiangzi/article/details/45689709

    http://c.biancheng.net/cpp/html/3052.html

  • 相关阅读:
    B-Suffix Array
    1 or 2
    Boundary
    Fake Maxpooling
    Cover the Tree
    Omkar and Circle
    20.5.31
    Yet Another Yet Another Task
    Codeforces Round #373 (Div. 2)E. Sasha and Array +线段树+矩阵快速幂
    2018 Multi-University Training Contest 2(Naive Operations ) hdu6315
  • 原文地址:https://www.cnblogs.com/zkfopen/p/9382705.html
Copyright © 2020-2023  润新知