• Linux _UDP 浅解


    UDP通信

    1. TCP与UDP
      当使用网络套接字通信时,
      套接字的“域”都取AF_INET;
      套接字的type:
      SOCK_STREAM 此时,默认使用TCP协议进行通信。
      SOCK_DGRAM 此时,默认使用UDP协议进行通信。

      TCP通信,是一个有序的、可靠的、面向连接的
      UDP通信,是不保证有序到达的数据报服务。(在局域网内,使用UDP已很可靠)

    2. 使用UDP通信
      与TCP通信使用上的区别:
      1)创建套接字时的type(参数2)不同。
      TCP通信,使用SOCK_STREAM
      UDP通信,使用SOCK_DGRAM

      2)发送数据和接收数据时,使用的接口不同
      TCP通信,发送数据,使用write(或send)
      接收数据,使用read(或recv)
      UDP特性,发送数据,使用sendto
      接收数据,服务器端使用recvfrom
      客户端使用recv

      3)不需要使用listen
      4)不需要先建立连接(TCP客户端和服务器端分别使用connect和receive建立连接)

      步骤总结:
      基于UDP的网络套接字通信
      服务器端
      (1) 创建一个网络套接字
      (2) 设置服务器地址
      (3) 绑定该套接字,使得该套接字和对应的端口关联起来
      (4) 循环处理客户端请求
      使用recvfrom等待接收客户端发送的数据
      使用sendto发送数据至客户端

      客户端
      (1) 创建一个套接字
      (2) 设置服务器地址
      (3) 使用sendto向服务器端(接收端)发送数据
      (4) 使用recv接受数据

    3. sendto与recvfrom、recv
      1) sendto
      功能:UDP服务器或客户端用于发送数据
      原型:int sendto (int sockfd, // 套接字
      void *buff, // 发送缓存区
      size_t len, // 发送缓冲区的长度
      init flags, // 标志,一般取0
      struct sockaddr *to, // 目的主机地址
      socklen_t tolen // 目的主机地址长度
      );
      返回值:成功,返回实际发送数据的字节数
      失败,返回-1

      2) recvfrom
      功能:UDP服务器用于接收数据
      原型: 与sendto类似。
      int recvfrom (int sockfd, // 套接字
      void *buff, // 接收缓存区
      size_t len, // 接受缓冲区的长度
      init flags, // 标志,一般取0
      struct sockaddr *to, // 源主机地址
      socklen_t *tolen // 源主机地址长度
      );
      注意:参数6必须要初始化为对应地址的长度!
      3) recv
      功能:UDP客户端用于接收数据
      原型: ssize_t recv (int sockfd, void *buf, size_t len, int flags);
      注意: 该调用的参数不需要指定地址。
      因为当使用udp时,对应的套接字被自动绑定在一个短暂的动态的端口上。

    4. 实例
      server1.c / client1.c 服务器接收、客户端发送
      server2.c / client2.c 服务器收发、客户方发送、接收。

    demo
    server1.c

    #include <sys/un.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #define BUFF_SIZE 1024
    
    int main(void)
    {
        int server_sockfd;
        int client_sockfd;
        char ch;
        int ret;
        int recv_len;
        char buff[BUFF_SIZE];
    
         //”√”⁄UNIXœµÕ≥ƒ⁄≤øÕ®–≈µƒµÿ÷∑£¨ struct sockaddr_un
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        int client_addr_len;
    
        server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
        // …Ë÷√∑˛ŒÒ∆˜µÿ÷∑
        server_addr.sin_family = AF_INET;  //µÿ÷∑µƒ”Ú£¨œ‡µ±”⁄µÿ÷∑µƒ¿‡–Õ, AF_UNIX±Ì æµÿ÷∑Œª”⁄UNIXœµÕ≥ƒ⁄≤ø
        server_addr.sin_addr.s_addr = INADDR_ANY;  //inet_addr("10.10.0.9");
        server_addr.sin_port = htons(9000);
    
        // ∞Û∂®∏√Ã◊Ω”◊÷£¨ πµ√∏√Ã◊Ω”◊÷∫Õ∂‘”¶µƒœµÕ≥Ã◊Ω”◊÷Œƒº˛πÿ¡™∆¿¥°£
        ret = bind(server_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
        if (ret == -1) {
            perror("bind");
            exit(1);
        }
    
        // ¥¥Ω®Ã◊Ω”◊÷∂”¡–£¨ ±£¥ÊΩ¯»Î∏√∑˛ŒÒ∆˜µƒøÕªß∂À«Î«Û°£
        //ret = listen(server_sockfd, 5);
    
        // —≠ª∑¥¶¿ÌøÕªß∂À«Î«Û
        while (1) {
    
            printf("server waiting
    ");
    
            // µ»¥˝≤¢Ω” ’øÕªß∂À«Î«Û
            //client_sockfd = accept(server_sockfd,  (struct sockaddr*)&client_addr, &client_addr_len);
                  recv_len = recvfrom(server_sockfd, buff, sizeof(buff) , 0, 
                                               (struct sockaddr*)&client_addr, &client_addr_len);
            if (recv_len < 0) {
                perror("recvfrom");
                exit(errno);
            }
    
            printf("received: %s
    ", buff); 
        }
    
        close(server_sockfd);
    
        return 0;   
    }
    

    client1.c

    #include <sys/un.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #define BUFF_SIZE 1024
    
    int main(void)
    {
        int sockfd;
        struct sockaddr_in server_addr;
        int ret;
        int c;
        char buff[BUFF_SIZE];
    
        // ¥¥Ω®“ª∏ˆÃ◊Ω”◊÷
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
        // …Ë÷√∑˛ŒÒ∆˜µÿ÷∑
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr("10.10.0.9");
        server_addr.sin_port = htons(9000);
    
           // œÚ∑˛ŒÒ∆˜∑¢ÀÕ ˝æ›
           strcpy(buff, "hello world");
           ret = sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
        if (ret == -1) {
            perror("sendto");
            exit(errno);
        }
    
        printf("ret = %d
    ", ret);
    
    
        return 0;   
    }
    

    server2.c

    #include <sys/un.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #define BUFF_SIZE 1024
    
    static void str2up(char *str)
    {
        while(*str) {
            if (*str >= 'a'  && *str <= 'z') {
                *str = *str - 'a' + 'A';
            }
    
            str++;
        }
    }
    
    int main(void)
    {
        int server_sockfd;
        int client_sockfd;
        char ch;
        int ret;
        int recv_len;
        int send_len;
        char buff[BUFF_SIZE];
    
         //”√”⁄UNIXœµÕ≥ƒ⁄≤øÕ®–≈µƒµÿ÷∑£¨ struct sockaddr_un
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        int client_addr_len;
    
        server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
        // …Ë÷√∑˛ŒÒ∆˜µÿ÷∑
        server_addr.sin_family = AF_INET;  //µÿ÷∑µƒ”Ú£¨œ‡µ±”⁄µÿ÷∑µƒ¿‡–Õ, AF_UNIX±Ì æµÿ÷∑Œª”⁄UNIXœµÕ≥ƒ⁄≤ø
        server_addr.sin_addr.s_addr = INADDR_ANY;  //inet_addr("10.10.0.9");
        server_addr.sin_port = htons(9000);
    
        // ∞Û∂®∏√Ã◊Ω”◊÷£¨ πµ√∏√Ã◊Ω”◊÷∫Õ∂‘”¶µƒœµÕ≥Ã◊Ω”◊÷Œƒº˛πÿ¡™∆¿¥°£
        ret = bind(server_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
        if (ret == -1) {
            perror("bind");
            exit(1);
        }
    
        // ¥¥Ω®Ã◊Ω”◊÷∂”¡–£¨ ±£¥ÊΩ¯»Î∏√∑˛ŒÒ∆˜µƒøÕªß∂À«Î«Û°£
        //ret = listen(server_sockfd, 5);
    
        // —≠ª∑¥¶¿ÌøÕªß∂À«Î«Û
        while (1) {
    
            printf("server waiting
    ");
    
            // µ»¥˝≤¢Ω” ’øÕªß∂À«Î«Û
            //client_sockfd = accept(server_sockfd,  (struct sockaddr*)&client_addr, &client_addr_len);
                  recv_len = recvfrom(server_sockfd, buff, sizeof(buff) , 0, 
                                               (struct sockaddr*)&client_addr, &client_addr_len);
            if (recv_len < 0) {
                perror("recvfrom");
                exit(errno);
            }
    
            printf("received: %s
    ", buff); 
    
            str2up(buff);
            send_len = sendto(server_sockfd, buff, strlen(buff)+1, 0,
                                    (struct sockaddr*)&client_addr, client_addr_len);
            if (send_len == -1) {
                perror("sendto");
                exit(errno);
            }
    
            //printf("send_len=%d
    ", send_len);                  
        }
    
        close(server_sockfd);
    
        return 0;   
    }
    

    client2.c

    #include <sys/un.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    
    #define BUFF_SIZE 1024
    
    int main(void)
    {
        int sockfd;
        struct sockaddr_in server_addr;
        int ret;
        int c;
        char buff[BUFF_SIZE];
        socklen_t addr_len;
    
        // ¥¥Ω®“ª∏ˆÃ◊Ω”◊÷
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    
        // …Ë÷√∑˛ŒÒ∆˜µÿ÷∑
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = inet_addr("10.10.0.99");
        server_addr.sin_port = htons(9000);
    
           // œÚ∑˛ŒÒ∆˜∑¢ÀÕ ˝æ›
           strcpy(buff, "hello world");
           ret = sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
        if (ret == -1) {
            perror("sendto");
            exit(errno);
        }
    
        printf("send %d bytes
    ", ret);
    
        ret = recv(sockfd, buff, sizeof(buff), 0);
        if (ret == -1) {
            perror("recvfrom");
            exit(errno);
        }
    
        printf("received %d bytes
    ", ret);
        printf("received: %s
    ", buff); 
    
        return 0;   
    }
    
  • 相关阅读:
    如何去除ecshop标题和网站底部的Powered by ECShop
    ecshop标签
    安装Wamp后 Apache无法启动的解决方法
    wamp5中的apache不能启动,80端口被占用
    iOS UI-AlertView(警示框)和ActionSheet(选择框、操作表单)
    iOS UI-三种简单的动画设置
    iOS UI-IOS开发中Xcode的一些使用技巧
    iOS UI-九宫格
    iOS开发-开发文档安装
    iOS UI-创建空项目
  • 原文地址:https://www.cnblogs.com/Sico2Sico/p/5384194.html
Copyright © 2020-2023  润新知