zoukankan      html  css  js  c++  java
  • 基于UDP的客户端和服务器端的代码设计

    实验平台

    linux

    实验内容

    编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号。

    实验原理

    UDP是无需连接的通信,其主要实现过程如下:

    同样,我们可以按照上一篇博客:基于TCP的客户端和服务器端的代码设计 的办法,将服务器代码分成两部分,一个是初始化,一个是收发数据。但是UDP服务器初始化较为简单,也可以直接写在main函数里。

    UDP和TCP在读写数据上较为不同的是,sendto()和recvfrom(),这两个函数较为复杂。通过man手册查询得到:

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

    参数1:文件描述符;  参数2:要发送的buf数据,是个指针
    参数3:目的地的地址,是个指针,在使用时需要强制类型转换成(struct sockaddr *)  参数4:目的地的地址长度。具体的例子看下面代码

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

    参数1:文件描述符;  参数2:要接收的buf缓冲区

    参数3:接收的来源地址,在使用时需要强制类型转换成(struct sockaddr *)  参数4:一个指针,指向地址长度。具体的例子看下面代码

    服务器端代码:udpserver.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h> 
    #include <sys/socket.h>
    #include <sys/types.h>
    
    #define BUFFER_SIZE 100
    #define PORT 1234
    
    int32_t main(int32_t argc,char *argv[])
    {
        struct sockaddr_in server;
        struct sockaddr_in client;
        char buf[BUFFER_SIZE];
        int32_t len = sizeof(client);
        int32_t ret = 0;
        int32_t file_len = 0;
    
        if (argc != 2)
        {
            printf("Usage ./server [ip]
    ");
            return -1;
        }
        int32_t sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0)
        {
            perror("create socket failed!");
            exit(1);
        }
    
        bzero(&server, sizeof(struct sockaddr_in));
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);     /**< 主机字节序转化成网络字节序 */
        server.sin_addr.s_addr = inet_addr(argv[1]);                /**< 字符串转换in_addr的函数 */
    
        /**< 绑定服务器 */
        if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)    
        {
            perror("bind failed!");
            exit(1);
        }
        
        ret = recvfrom(sockfd, buf, BUFFER_SIZE, 0, (struct sockaddr *)&client, &len);
        if (ret < 0)
        {
            perror("recvfrom failed!");
            exit(1);
        }
        buf[ret] = '';
        printf("client message: %s
    ", buf);
        printf("client's ip is %s, port is %d.
    ", inet_ntoa(client.sin_addr), htons(client.sin_port));
    
        /**< 向客户端发送信息 */
        if (sendto(sockfd, "Welcome to server", BUFFER_SIZE, 0, (struct sockaddr *)&client, len) < 0)
        {
            perror("send file len to client error");
        }
    
        close(sockfd);
        return 0;
    }

    客户端代码:udpclient.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h> 
    #include <sys/socket.h>
    #include <sys/types.h>
    
    #define BUFFER_SIZE 100
    #define PORT 1234
    
    int32_t main(int argc,char *argv[])
    {
        struct sockaddr_in server;
        struct sockaddr_in peer;
        char buf[BUFFER_SIZE];
        int32_t len = sizeof(peer);
        char sendbuf[BUFFER_SIZE] = "welcome to client";
        int32_t num = 0;
    
        if (argc != 2)
        {
            printf("Usage ./client ip
    ");
            exit(1);
        }
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0)
        {
            perror("create socket failed!");
            exit(1);
        }
        bzero(&server, sizeof(struct sockaddr_in));
        server.sin_family = AF_INET;
        server.sin_port = htons(PORT);
        server.sin_addr.s_addr = inet_addr(argv[1]);
    
        if (sendto(sockfd, sendbuf, BUFFER_SIZE, 0, (struct sockaddr *)&server, sizeof(server)) < 0)
        {
            perror("sendto socket failed!");
            exit(1);
        }
    
        if ((num = recvfrom(sockfd, buf, BUFFER_SIZE, 0, (struct sockaddr *)&peer, &len)) < 0)
        {
            perror("recvfrom socket failed!");
            exit(1);
        }
        
        buf[num] = '';
        printf("Server Message: %s
    ", buf);
    
        close(sockfd);
    
        return 0;
    }

    Makefile

    all:server client
    
    server:udpserver.c
        gcc udpserver.c -o server
        
    client:udpclient.c
        gcc udpclient.c -o client
        
    clean:
        rm -rf server client

    实验结果

     

  • 相关阅读:
    C#实现二维码生成与解码
    js中正则表达式使用
    Busybox镜像
    linux删除文件后,空间未释放的一种情况,使用lsof查看
    linux中.nfsxxxx引起的文件无法删除
    linux中的查找命令find,locate,which,whereis
    openj9
    Ali流量控制中间件Sentinel
    LDAP认证模式简介
    nginx支持ipv6
  • 原文地址:https://www.cnblogs.com/gezhuangzhuang/p/12672208.html
Copyright © 2011-2022 走看看