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

    实验环境

    linux

    注意:

    使用UDP广播,是客户端发送广播消息,服务器端接收消息。实际上是客户端探测局域网中可用服务器的一种手段。客户端发送,服务器端接收,千万不能弄混淆!!!

    为了避免混淆,本文不使用client、server字眼。而使用send,recv

    构建send_broadcast.c。发送广播消息,并打印接收端的IP和端口,退出时发送"done"消息

    流程:创建一个socket,并用setscokopt函数声明这是一个broadcast类型的socket,然后通过这个socket向INADDR_BROADCAST("255.255.255.255")发送消息。

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    
    #define PORT 1234
    #define BUFFER_SIZE 100
    
    int32_t main()
    {
        char msg[BUFFER_SIZE] = "I am a broadcast message";
        int32_t nb = 0; 
        struct sockaddr_in addrto;    
        int32_t nlen=sizeof(addrto); 
    
        int32_t sockfd = -1;  
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)   
        {     
            perror("create socket failed
    ");   
            return -1;  
        }    
    
        const int opt = 1;  
        //设置该套接字为广播类型,  
        nb = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST | SO_REUSEADDR, &opt, sizeof(opt));  
        if(nb == -1)  
        {  
            perror("set socket error...
    ");  
            return -1;  
        }  
    
        /**< 接收者地址结构 */
        bzero(&addrto, sizeof(struct sockaddr_in));  
        addrto.sin_family = AF_INET;    
        addrto.sin_addr.s_addr = htonl(INADDR_BROADCAST);  
        addrto.sin_port = htons(PORT);  
      
        int ret = sendto(sockfd, msg, BUFFER_SIZE, 0, (struct sockaddr*)&addrto, nlen);  
        if (ret < 0)  
        {  
            perror("send error.
    ");  
        } 
    
        /**< 打印接收者的IP和端口号 */
        printf("recver's ip is %s, port is %d.
    ", inet_ntoa(addrto.sin_addr), htons(addrto.sin_port));
    
        bzero(msg, BUFFER_SIZE);
        memcpy(msg, "done", 5);
    
        sendto(sockfd, msg, BUFFER_SIZE, 0, (struct sockaddr*)&addrto, nlen);
        
        printf("Done
    ");
        return 0;  
    }  

    构建recv_broadcast.c 接收广播消息,打印发送端的IP和端口号,在接收到done后停止并退出

    流程:创建一个socket并绑定INADDR_ANY的本地地址,接收消息

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
      
    #define PORT 1234
    #define BUFFER_SIZE 100
    
    int32_t main()
    {
        struct sockaddr_in addrto;
        
        struct sockaddr_in from;
        int32_t listenfd = -1;
        int32_t len = sizeof(from);
        char recvbuf[BUFFER_SIZE];
    
        if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)   
        {     
            perror("create socket failed
    ");   
            return -1;  
        } 
        
        bzero(&addrto, sizeof(struct sockaddr_in));  
        bzero(&from, sizeof(struct sockaddr_in));  
        addrto.sin_family = AF_INET;
        addrto.sin_port = htons(PORT);  
        addrto.sin_addr.s_addr = htonl(INADDR_ANY);  
    
        const int opt = 1;  
        int32_t nb = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  
        if(nb == -1)  
        {  
            perror("set socket error...
    ");  
            return -1;  
        }  
    
        /**< 绑定自己的地址 */
        if (bind(listenfd, (struct sockaddr *)&addrto, len) == -1)
        {
            perror("bind error
    ");
            return -1;
        }
    
        while (1)
        {
            //从广播地址接收消息  
            int ret = recvfrom(listenfd, recvbuf, BUFFER_SIZE, 0, (struct sockaddr*)&from, &len);  
            if (ret > 0)  
            {  
                recvbuf[ret] = '';
                printf("receive messgse:%s
    ", recvbuf);
                if (!strcmp("done", recvbuf))
                {
                    break;
                }
            }  
            else  
            {    
                perror("recv error.
    ");  
    
            } 
            bzero(recvbuf, BUFFER_SIZE);
    
            /**< 打印发送者的ip和端口号 */
            printf("sender's ip is %s, port is %d.
    ", inet_ntoa(from.sin_addr), htons(from.sin_port));
        }
    
        close(listenfd);
        printf("Done
    ");
        return 0;  
    }  

     Makefile

    all:sender recver
    sender:
        gcc send_broadcast.c -o sender
    
    recver:
        gcc recv_broadcast.c -o recver
    
    clean:
        rm -rf sender recver
  • 相关阅读:
    Android Studio获取开发版SHA1值和发布版SHA1值的史上最详细方法
    Android Studio 汉化包
    Genymotion模拟器下载及安装步骤详解
    react native 搭建开发环境——Mac
    ::before和::after伪元素的用法
    前端面试题整理
    echarts图表自适应
    下拉加载更多
    vue之webpack+vuecli打包生成资源相对引用路径与背景图片的正确引用
    微信小程序之tab切换
  • 原文地址:https://www.cnblogs.com/gezhuangzhuang/p/12674746.html
Copyright © 2011-2022 走看看