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
  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/gezhuangzhuang/p/12674746.html
Copyright © 2011-2022 走看看