美文网首页
基于UDP协议的服务器/客户端编程

基于UDP协议的服务器/客户端编程

作者: arkliu | 来源:发表于2022-12-03 08:17 被阅读0次

    UDP客户端服务器编程模型

    image.png

    发送数据相关api

    #include <sys/types.h>
    #include <sys/socket.h>
    
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    成功返回发送字节数,失败返回-1
    
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                  const struct sockaddr *dest_addr, socklen_t addrlen);
    成功返回发送字节数,失败返回-1
    
    ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    成功返回发送字节数,失败返回-1
    

    接收数据相关api

    #include <sys/types.h>
    #include <sys/socket.h>
    
    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                    struct sockaddr *src_addr, socklen_t *addrlen);
    ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
    
    返回消息的字节数,无消息返回0,出错返回-1
    
    

    基于UDP协议的服务器

    接收客户端发送的数据,并发送当前时间给客户端

    #include<sys/socket.h>
    #include <netdb.h>
    #include<unistd.h>
    #include<string.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<signal.h>
    #include<time.h>
    #include<arpa/inet.h>
    
    int sockfd;
    
    void sig_handler(int sig_no) {
        if(sig_no == SIGINT) {
            printf("server close\n");
            close(sockfd);
            exit(1);
        }
    }
    
    //输出客户端的信息
    void out_addr(struct sockaddr_in *clientaddr) {
        char ip[16];
        int port;
        memset(ip, 0, sizeof(ip));
        inet_ntop(AF_INET,
                &clientaddr->sin_addr.s_addr,ip,sizeof(ip));
        port = ntohs(clientaddr->sin_port);
        printf("client: %s(%d\n", ip, port);
    }
    
    // 和客户端进行通信
    void do_service() {
        struct sockaddr_in clientaddr;
        socklen_t len = sizeof(clientaddr);
        char buffer[1024];
        memset(buffer, 0 , sizeof(buffer));
        // 接收客户端的数据报文
        if(recvfrom(sockfd, buffer, sizeof(buffer), 0,
                    (struct sockaddr*)&clientaddr, &len) < 0) {
            perror("recvfrom error");
        } else {
            out_addr(&clientaddr);
            printf("client send info:%s\n", buffer);
            //向客户端发送数据报文
            long int t = time(NULL);
            char *ptr = ctime(&t);
    
            size_t size = strlen(ptr) * sizeof(char);
            if(sendto(sockfd, ptr, size, 0, 
                (struct sockaddr*)&clientaddr, len) <0) {
                perror("sendto error");
            }
        }
    }
    
    int main(int argc, char* argv[]) {
        if (argc < 2){
            printf("usage:%s #port\n",argv[0]);
            exit(1);
        }
        
        if (signal(SIGINT, sig_handler) == SIG_ERR){
            perror("signale sigint error");
            exit(1);
        }
        /*步骤1:创建socket*/
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if(sockfd < 0) {
            perror("socket error");
            exit(1);
        }
        int ret;
        int opt = 1;  
        //设置套接字选项
        if((ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, &opt,sizeof(opt))) < 0) {
            perror("setsockopt error");
            exit(1);
        }
    
        /*步骤2:调用bind函数对socket和地址进行绑定*/
        struct sockaddr_in serveradr;
        memset(&serveradr, 0, sizeof(serveradr));
        serveradr.sin_family = AF_INET;
        serveradr.sin_port = htons(atoi(argv[1]));
        serveradr.sin_addr.s_addr = INADDR_ANY;
        if(bind(sockfd, (struct sockaddr*)&serveradr,sizeof(serveradr)) < 0) {
            perror("bind error");
            exit(1);
        }
        /*步骤3:和客户端进行双向的数据通信*/
        while(1) {
            do_service();
        }
        return 0;
    }
    
    

    基于UDP协议的客户端

    #include<sys/socket.h>
    #include <netdb.h>
    #include<unistd.h>
    #include<string.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<signal.h>
    #include<time.h>
    #include<arpa/inet.h>
    
    int main(int argc, char* argv[]) {
    
        if (argc < 3){
            printf("usage:%s ip port\n",argv[0]);
            exit(1);
        }
        /*步骤1:创建socket*/
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd < 0){
            perror("socket error");
            exit(1);
        }
    
        /*步骤2:调用recvfrom和sendto等函数和服务器进行双向通信*/
        struct sockaddr_in serveraddr;
        memset(&serveraddr, 0 , sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(atoi(argv[2])); // port
        inet_pton(AF_INET, argv[1],
                    &serveraddr.sin_addr.s_addr); // ip
    
        char buffer[1024] = "hello world";
        if(sendto(sockfd, buffer, sizeof(buffer), 0,
                    (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0){
            perror("sendto error");
            exit(1);
        }else{
            // 接收服务器端发送的数据报文
            memset(buffer, 0, sizeof(buffer));
            size_t size;
            if((size = recv(sockfd,buffer, sizeof(buffer), 0)) < 0) {
                perror("recv error");
                exit(1);
            } else {
                printf("%s", buffer);
            }
        }         
        return 0;
    }
    

    服务器:


    image.png

    客户端:


    image.png

    相关文章

      网友评论

          本文标题:基于UDP协议的服务器/客户端编程

          本文链接:https://www.haomeiwen.com/subject/ctqsfdtx.html