美文网首页C语言
7.UDP网络通信

7.UDP网络通信

作者: 石不琢 | 来源:发表于2017-08-24 08:53 被阅读0次

    1. 流程

    服务器:
        创建套接字 socket( )
        填充服务器网络信息结构体 sockaddr_in
        将套接字与服务器网络信息结构体绑定 bind( )
        进行通信 recvfrom( )/sendto( )
    客户端:
        创建套接字 socket( )
        填充服务器网络信息结构体 sockaddr_in
        进行通信 sendto( )/recvfrom( )
    

    2. sendto

    #include <sys/socket.h>
    
    ssize_t sendto(int socket, const void *message, size_t length,
           int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
    功能:发送数据
    参数:
        socket:文件描述符
        message:发送的数据
        length:数据的长度
        flags:标志位,一般为0
        dest_addr:目的地址(发送给谁)
        dest_len:addr的大小
    返回值:
        成功:发送数据的长度
        失败:-1
    

    3.recvfrom

    #include <sys/types.h>
    #include <sys/socket.h>
    
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
            struct sockaddr *src_addr, socklen_t *addrlen);
    功能:接收数据
    参数:
        sockfd:文件描述符
        buf:接收的数据
        len:部分的长度
        flags:标志位,一般为0
        src_addr:源的地址(接收谁的数据,自动填充)
        addrlen:addr的大小
    返回值:
        成功:接收的数据的长度
        失败:-1
    

    服务器端

    #include <stdio.h> //printf
    #include <arpa/inet.h> //inet_addr htons
    #include <sys/types.h>
    #include <sys/socket.h> //scoket bind listen accept connect
    #include <netinet/in.h> //sockaddr_in
    #include <stdlib.h> //exit
    #include <unistd.h> //close
    #include <string.h> //strcat
    #include <strings.h>
    
    #define N 128
    #define errlog(errmsg) do{perror(errmsg);\
                              printf("%s-->%s-->%d\n", __FILE__, __func__, __LINE__);\
                              exit(1);\
                             }while(0)
    
    int main(int argc, const char *argv[])
    {
        int sockfd;
        struct sockaddr_in serveraddr, clientaddr;
        socklen_t addrlen = sizeof(serveraddr);
        char buf[N] = {};
    
        //初始化结构体
        //bzero memset
        bzero(&serveraddr, addrlen);
        bzero(&clientaddr, addrlen);
    
        if(argc < 3)
        {
            printf("the argument is too less\n");
            exit(1);
        }
    
        //第一步:创建套接字
        if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
            errlog("fail to socket");
        }
    
        //第二步:填充服务器网络信息结构体
        //inet_addr:将点分十进制IP地址转化为网络字节序的整型数据
        //htons:将主机字节序转化为网络字节序
        //atoi:将数字型字符串转化为整型数据
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));
    
        //第三步:将套接字域网络信息结构体绑定
        if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
        {
            errlog("fail to bind");
        }
    
        ssize_t ret;
        while(1)
        {
            if((ret = recvfrom(sockfd, buf, N, 0, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
            {
                errlog("fail to recvfrom");
            }
            else
            {
                if(strncmp(buf, "quit", 4) == 0)
                {
                    break;
                }
                else
                {
                    printf("%s --> %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                    printf("client:%s\n", buf);
    
                    strcat(buf, " *_*");
    
                    if(sendto(sockfd, buf, N, 0, (struct sockaddr *)&clientaddr, addrlen) < 0)
                    {
                        errlog("fail to sendto");
                    }
                }
            }
        }
    
        close(sockfd);
        
        return 0;
    }
    

    客户端

    #include <stdio.h> //printf
    #include <arpa/inet.h> //inet_addr htons
    #include <sys/types.h>
    #include <sys/socket.h> //scoket bind listen accept connect
    #include <netinet/in.h> //sockaddr_in
    #include <stdlib.h> //exit
    #include <unistd.h> //close
    #include <string.h> 
    
    #define N 128
    #define errlog(errmsg) do{perror(errmsg);\
                              printf("%s-->%s-->%d\n", __FILE__, __func__, __LINE__);\
                              exit(1);\
                             }while(0)
    
    int main(int argc, const char *argv[])
    {
        int sockfd;
        struct sockaddr_in serveraddr, clientaddr;
        socklen_t addrlen = sizeof(serveraddr);
        char buf[N] = {};
    
        if(argc < 3)
        {
            printf("the argument is too less\n");
            exit(1);
        }
    
        //第一步:创建套接字
        if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
            errlog("fail to socket");
        }
    
        //第二步:填充服务器网络信息结构体
        //inet_addr:将点分十进制IP地址转化为网络字节序的整型数据
        //htons:将主机字节序转化为网络字节序
        //atoi:将数字型字符串转化为整型数据
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
        serveraddr.sin_port = htons(atoi(argv[2]));
    
        while(1)
        {
            fgets(buf, N, stdin);
            buf[strlen(buf) - 1] = '\0';
    
            if(sendto(sockfd, buf, N, 0, (struct sockaddr *)&serveraddr, addrlen) < 0)
            {
                errlog("fail to sendto");
            }
    
            if(strncmp(buf, "quit", 4) == 0)
            {
                break;
            }
            else
            {
                if(recvfrom(sockfd, buf, N, 0, NULL, NULL) < 0)
                {
                    errlog("fail to recvfrom");
                }
    
                printf("server:%s\n", buf);
            }
        }
    
        close(sockfd);
    
        return 0;
    }
    

    相关文章

      网友评论

        本文标题:7.UDP网络通信

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