UDP通讯测试

参考资料:UNIX网络编程

实验平台:PC为client,RaspberryPi为server

基本类型和接口函数,参考man手册

    #include <sys/socket.h>

       struct sockaddr {
           sa_family_t     sa_family;      /* Address family */
           char            sa_data[];      /* Socket address */
       };

       #include <netinet/in.h>

       struct sockaddr_in {
           sa_family_t     sin_family;     /* AF_INET */
           in_port_t       sin_port;       /* Port number */
           struct in_addr  sin_addr;       /* IPv4 address */
       };

       struct in_addr {
           in_addr_t s_addr;
       };

       typedef uint32_t in_addr_t;
       typedef uint16_t in_port_t;


       #include <sys/socket.h>
       ssize_t sendto(int sockfd, const void buf[.len], size_t len, int flags,
                      const struct sockaddr *dest_addr,
                      socklen_t addrlen);
       
       ssize_t recvfrom(int sockfd, void buf[restrict .len], size_t len, int flags,
                        struct sockaddr *src_addr,
                        socklen_t *addrlen);
       
            
      #include <arpa/inet.h>
       int inet_pton(int af, const char *restrict src, void *restrict dst);
       
       const char *inet_ntop(int af, const void *restrict src, char dst[restrict .size], socklen_t size);

       
       
       
       #include <arpa/inet.h>

       int inet_pton(int af, const char *restrict src, void *restrict dst);

服务器端


#define SERV_PORT 9877 /* TCP and UDP */


void dg_echo(int sockfd, struct sockaddr *p_cli_addr, socklen_t addr_len)
{
    int  n;
    socklen_t len;

    char  mesg[MAXLINE];
    char addr[addr_len];

    for ( ; ; )
    {
        len = addr_len;
        n = recvfrom(sockfd, mesg, MAXLINE, 0, p_cli_addr, &len);

        if(len != 0)
        {
            inet_ntop(AF_INET, &((struct sockaddr_in *)p_cli_addr)->sin_addr, addr, len);
            printf("Received %d Bytes : %s From client %s\n", n, mesg, addr);
        }

        printf("Now send back!\n");
        fflush(stdout);

        sendto(sockfd, mesg, n, 0, p_cli_addr, len);
    }
}

void server_main(void)
{
    int sockfd;
    struct sockaddr_in  serv_addr, cli_addr;


    /* IPPROTO_IP = 0 */      /* Dummy protocol for TCP.  */
    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sockfd < 0)
    {
        perror("socket fail");
    }
    else
    {
        memset(&serv_addr, 0, sizeof(serv_addr));

        serv_addr.sin_family = AF_INET;

        /* /usr/include/netinet/in.h */
        /* Address to accept any incoming messages.  */
        /* #define INADDR_ANY   ((in_addr_t) 0x00000000) */
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        //inet_pton(AF_INET, "192.168.39.39", &servaddr.sin_addr);
        serv_addr.sin_port = htons(SERV_PORT);

        bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

        dg_echo(sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr));
    }
}

客户端

void dg_cli(FILE *fp, int sockfd, const struct sockaddr *p_serv_addr, socklen_t addr_len)
{
    int n;
    socklen_t len;

    struct sockaddr_in reply_addr;
    char sendline[MAXLINE];
    char recv_buf[MAXLINE + 1];
    char recv_addr[addr_len];

    while (fgets(sendline, MAXLINE, fp) != NULL)
    {
        sendto(sockfd, sendline, strlen(sendline), 0, p_serv_addr, addr_len);

        printf("send successfully!\n");
        fflush(stdout);

        n = recvfrom(sockfd, recv_buf, MAXLINE, 0, (struct sockaddr *)&reply_addr, &len);

        printf("receive success!\n");
        fflush(stdout);

        inet_ntop(AF_INET, &reply_addr.sin_addr, recv_addr, len);

        if((len != addr_len) || (memcmp(p_serv_addr, (struct sockaddr *)&reply_addr, len) != 0))
        {
            printf("Replied from %s ignored!\n", recv_addr);
            continue;
        }
        else
        {
            printf("Replied from %s with:\n", recv_addr);
        }

        recv_buf[n] = '\0';   /* null terminate */
        fputs(recv_buf, stdout);
    }
}

void client_main(const char *src)
{
    int  sockfd;
    struct sockaddr_in serv_addr;

    memset(&serv_addr, 0, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);

    inet_pton(AF_INET, src, &serv_addr.sin_addr);

    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if(sockfd < 0)
        perror("socket");
    else
    {
        printf("socket len: %ld\n", sizeof(serv_addr));
        dg_cli(stdin, sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    }

}

测试结果

客户端:

服务器:

补充知识:

程序员不应操作sockaddr结构,sockaddr是给操作系统用的
程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。

相关推荐

  1. qt的udp通讯

    2024-03-14 04:52:01       10 阅读
  2. imu测试--UDP、PTP

    2024-03-14 04:52:01       17 阅读
  3. SFML udp通信实例

    2024-03-14 04:52:01       17 阅读
  4. Ubuntu下udp通信

    2024-03-14 04:52:01       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-14 04:52:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-14 04:52:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-14 04:52:01       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-14 04:52:01       20 阅读

热门阅读

  1. npm报证书过期 certificate has expired问题(已解决)

    2024-03-14 04:52:01       21 阅读
  2. C# 单例模式

    2024-03-14 04:52:01       21 阅读
  3. 阿里云分布式深度学习训练架构Whale

    2024-03-14 04:52:01       21 阅读
  4. 抓包分析工具的小米加步枪版本

    2024-03-14 04:52:01       20 阅读
  5. 动态规划 Leetcode 416 分割等和子集

    2024-03-14 04:52:01       20 阅读
  6. 蓝桥杯---附近最小(典型的滑动窗口类型问题)

    2024-03-14 04:52:01       19 阅读
  7. eclipse-内存问题

    2024-03-14 04:52:01       19 阅读
  8. QT5.14.2 视频分帧:QT与FFmpeg的高效结合

    2024-03-14 04:52:01       21 阅读
  9. Llama-3即将发布:Meta公布其庞大的AI算力集群

    2024-03-14 04:52:01       21 阅读
  10. GO下grpc快速体验

    2024-03-14 04:52:01       19 阅读