zoukankan      html  css  js  c++  java
  • (十四)UDP协议的两个主要方法sendto和recvfrom详解

    在网络编程中,UDP运用非常广泛。很多网络协议是基于UDP来实现的,如SNMP等。大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的。

    本篇文章跟大家分享linux下UDP的使用和实现,主要介绍下sendto()和recvfrom()两个函数的使用,以及INADDR_ANY的说明,并在最后展示了一个经过自己测试可用的UDP Server和UDP Client的代码示例。

    关于UDP数据报

    UDP都是以数据报的形式进行发送和接收的,而TCP是以数据流的形式进行发送和接收的。数据报和数据流,这两者要区分开来。

    头文件

    #include <sys/types.h>
    #include <sys/socket.h>

    函数原型

    int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);

    int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

    函数说明

    sendto(),是把UDP数据报发给指定地址;recvfrom()是从指定地址接收UDP数据报。

    参数说明

    • s:            socket描述符。
    • uf:         UDP数据报缓存地址。
    • len:         UDP数据报长度。
    • flags:       该参数一般为0。
    • o:           sendto()函数参数,struct sockaddr_in类型,指明UDP数据发往哪里报。
    • olen:       对方地址长度,一般为:sizeof(struct sockaddr_in)。
    • from:   recvfrom()函数参数,struct sockaddr 类型,指明UDP数据从哪里收。  
    • fromlen:recvfrom()函数参数,struct sockaddr_in类型,指明从哪里接收UDP数据报。

    函数返回值

    对于sendto()函数,成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。

    对于recvfrom()函数,成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。

    UDP Server和Client源码实例

    UDP Server:

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netinet/in.h>

    #include <arpa/inet.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <string.h>

    #include <stdio.h>

     

    #defineUDP_TEST_PORT50001

     

    int main(int argC, char* arg[])

    {

    struct sockaddr_in addr;

    int sockfd, len = 0;

    int addr_len = sizeof(struct sockaddr_in);

    char buffer[256];

     

    /* 建立socket,注意必须是SOCK_DGRAM */

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

    perror ("socket");

    exit(1);

    }

     

    /* 填写sockaddr_in 结构 */

    bzero(&addr, sizeof(addr));

    addr.sin_family = AF_INET;

    addr.sin_port = htons(UDP_TEST_PORT);

    addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据

     

    /* 绑定socket */

    if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {

    perror("connect");

    exit(1);

    }

     

    while(1) {

    bzero(buffer, sizeof(buffer));

    len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 

      (struct sockaddr *)&addr ,&addr_len);

    /* 显示client端的网络地址和收到的字符串消息 */

    printf("Received a string from client %s, string is: %s ", 

    inet_ntoa(addr.sin_addr), buffer);

    /* 将收到的字符串消息返回给client端 */

    sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);

    }

     

    return 0;

    }

     

    // ----------------------------------------------------------------------------

    // End of udp_server.c

    UDP Client:

    #include <sys/types.h>

    #include <sys/socket.h>

    #include <netinet/in.h>

    #include <arpa/inet.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <string.h>

    #include <stdio.h>

     

    #defineUDP_TEST_PORT50001

    #define UDP_SERVER_IP "127.0.0.1"

     

    int main(int argC, char* arg[])

    {

    struct sockaddr_in addr;

    int sockfd, len = 0;

    int addr_len = sizeof(struct sockaddr_in);

    char buffer[256];

     

    /* 建立socket,注意必须是SOCK_DGRAM */

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

    perror("socket");

    exit(1);

    }

     

    /* 填写sockaddr_in*/

    bzero(&addr, sizeof(addr));

    addr.sin_family = AF_INET;

    addr.sin_port = htons(UDP_TEST_PORT);

    addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);

     

    while(1) {

    bzero(buffer, sizeof(buffer));

     

    printf("Please enter a string to send to server: ");

     

    /* 从标准输入设备取得字符串*/

    len = read(STDIN_FILENO, buffer, sizeof(buffer));

     

    /* 将字符串传送给server端*/

    sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);

     

    /* 接收server端返回的字符串*/

    len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 

          (struct sockaddr *)&addr, &addr_len);

    printf("Receive from server: %s ", buffer);

    }

     

    return 0;

    }

     

    // ----------------------------------------------------------------------------

     

    // End of udp_client.c

    UDP Server:

    01 #include <sys/types.h>
    02 #include <sys/socket.h>
    03 #include <netinet/in.h>
    04 #include <arpa/inet.h>
    05 #include <unistd.h>
    06 #include <stdlib.h>
    07 #include <string.h>
    08 #include <stdio.h>
    09  
    10 #define UDP_TEST_PORT       50001
    11  
    12 int main(int argC, char* arg[])
    13 {
    14     struct sockaddr_in addr;
    15     int sockfd, len = 0;   
    16     int addr_len = sizeof(struct sockaddr_in);
    17     char buffer[256];  
    18  
    19     /* 建立socket,注意必须是SOCK_DGRAM */
    20     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    21         perror ("socket");
    22         exit(1);
    23     }
    24  
    25     /* 填写sockaddr_in 结构 */
    26     bzero(&addr, sizeof(addr));
    27     addr.sin_family = AF_INET;
    28     addr.sin_port = htons(UDP_TEST_PORT);
    29     addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据
    30  
    31     /* 绑定socket */
    32     if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {
    33         perror("connect");
    34         exit(1);
    35     }
    36  
    37     while(1) {
    38         bzero(buffer, sizeof(buffer));
    39         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
    40                        (struct sockaddr *)&addr ,&addr_len);
    41         /* 显示client端的网络地址和收到的字符串消息 */
    42         printf("Received a string from client %s, string is: %s ",
    43                 inet_ntoa(addr.sin_addr), buffer);
    44         /* 将收到的字符串消息返回给client端 */
    45         sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);
    46     }
    47  
    48     return 0;
    49 }
    50  
    51 // ----------------------------------------------------------------------------
    52 // End of udp_server.c

    UDP Client:

    01 #include <sys/types.h>
    02 #include <sys/socket.h>
    03 #include <netinet/in.h>
    04 #include <arpa/inet.h>
    05 #include <unistd.h>
    06 #include <stdlib.h>
    07 #include <string.h>
    08 #include <stdio.h>
    09  
    10 #define UDP_TEST_PORT       50001
    11 #define UDP_SERVER_IP       "127.0.0.1"
    12  
    13 int main(int argC, char* arg[])
    14 {
    15     struct sockaddr_in addr;
    16     int sockfd, len = 0;   
    17     int addr_len = sizeof(struct sockaddr_in);     
    18     char buffer[256];
    19  
    20     /* 建立socket,注意必须是SOCK_DGRAM */
    21     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    22         perror("socket");
    23         exit(1);
    24     }
    25  
    26     /* 填写sockaddr_in*/
    27     bzero(&addr, sizeof(addr));
    28     addr.sin_family = AF_INET;
    29     addr.sin_port = htons(UDP_TEST_PORT);
    30     addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);
    31  
    32     while(1) {
    33         bzero(buffer, sizeof(buffer));
    34  
    35         printf("Please enter a string to send to server: ");
    36  
    37         /* 从标准输入设备取得字符串*/
    38         len = read(STDIN_FILENO, buffer, sizeof(buffer));
    39  
    40         /* 将字符串传送给server端*/
    41         sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);
    42  
    43         /* 接收server端返回的字符串*/
    44         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
    45                        (struct sockaddr *)&addr, &addr_len);
    46         printf("Receive from server: %s ", buffer);
    47     }
    48  
    49     return 0;
    50 }
    51  
    52 // ----------------------------------------------------------------------------
    53 // End of udp_client.c

    上述代码是经过验证可用的。

  • 相关阅读:
    2020软件工程作业04
    2020软件工程作业03
    2020软件工程作业02
    2020软件工程作业01
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
    2020软件工程作业02
    软件工程作业01
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
  • 原文地址:https://www.cnblogs.com/zhangshenghui/p/6097497.html
Copyright © 2011-2022 走看看