• 【Socket】linux组播技术


    1.mystery引入

     

       1)本学期学了计算机网络,对一些网络底层的东西还是不大了解
       2)目前IP网络流行3种通信模式,分别是单播/广播与组播
       3)根据Internet关于IP地址的规定,IP地址分为A/B/C/D/E共5类
       4)A到C类地址是目前广泛应用的普通IP地址,E类地址保留为将来使用,D类地址即为组播地址,其网络号为固定的1110(前4位)
       5)若在加入一个组播组,需要利用IP_ADD_MEMBERSHIP,其中最重要的数据结构是struct ip_mreq
       6)IP_DROP_MEMBERSHIP 该选项用来从某个组播中退出
       7)服务器端:主要功能是通过指定一个多播地址,创建一个多播组
       8)客户端:主要功能是通过指定多播地址,加入多播组,在程序结束时,退出多播组
       9)调用setsockopt()函数,设置OP_DROP_MUMBERSHIP属性来退出一个多播。


    2.实例操作

     

    1)服务器端:

    //multisocketserver.c
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <stdlib.h>
    int main(void)
    {  
        int server_socket;
        struct sockaddr_in address;
                                                               
        server_socket = socket(AF_INET, SOCK_DGRAM, 0);
        if (server_socket < 0)
        {    
            perror("socket");
            return 0;
        } 
                                                               
        memset(&address, 0, sizeof(address)); 
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = inet_addr("224.0.0.1");
        address.sin_port = htons(5555);
                                                               
        while(1)
        {
            char buf[200];
            printf("input your word:>");
            scanf("%s",buf);
            if(sendto(server_socket, buf,sizeof(buf), 0,(struct sockaddr *)&address, sizeof(address)) < 0)
            {
                perror("sendto");
                return ;
            } 
        }
    }

    2)客户端:
    //mutisocketclient.c
    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(void)
    {
        struct ip_mreq multiaddress;
        int serveraddress_len;
        int client_socket;
        struct sockaddr_in serveraddress;
        /*bzero(&serveraddress, sizeof(serveraddress));*/
        memset(&serveraddress, 0, sizeof(serveraddress));
        serveraddress.sin_family = AF_INET;
        serveraddress.sin_addr.s_addr = htonl(INADDR_ANY);
        serveraddress.sin_port = htons(5555);
        if((client_socket = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
        {
            perror("socket");
            return 0;
        }
        int opt = 1;
        if(setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR,&opt, sizeof(opt)) < 0)
        {
            perror("setsockopt:SO_REUSEADDR");
            return 0;
        }
        if(bind(client_socket, (struct sockaddr *)&serveraddress, sizeof(serveraddress)) < 0)
        {
            perror("bind");
            return 0;
        }
                                              
        // 在同一个主机上进行广播设置套接口
        multiaddress.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
        multiaddress.imr_interface.s_addr = htonl(INADDR_ANY);
        //加入广播组
        if (setsockopt(client_socket,IPPROTO_IP,IP_ADD_MEMBERSHIP,&multiaddress, sizeof(multiaddress)) < 0)
        { 
            perror("IP_ADD_MEMBERSHIP");
            return 0;
        }
                                              
        while(1)
        {  
            char buf[200];
            serveraddress_len = sizeof(serveraddress);
            if(recvfrom(client_socket, buf, 200, 0,(struct sockaddr *)&serveraddress, &serveraddress_len) < 0)
            {
                perror("recvfrom"); 
            }
            printf("msg from server: %s
    ", buf);
                                                  
            if(strcmp(buf,"quit") == 0)
            {
                if(setsockopt(client_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,&multiaddress, sizeof(multiaddress)) < 0)
                {
                    perror("setsockopt:IP_DROP_MEMBERSHIP");
                } 
                close(client_socket);
                return 0;
            }
        }
    }



    3.mystery注解

     

       1)效果图



       2)由上图可见,程序依然没有达到目的,在组播组内的成员依然没有收到组播消息
       3)查看源代码并没有找到相应的错误,纠结
       4)多播底层实现如源代码所示,类似于QQ里面的群消息

    本文出自 “成鹏致远” 博客,请务必保留此出处http://infohacker.blog.51cto.com/6751239/1155123

  • 相关阅读:
    手动挂接NFS
    Linux中移动,复制,删除,打包排除某个目录或文件
    关于职业规划,尤其值得我们程序员学习、思考
    深入探究VC —— 链接器link.exe(4)
    用VC实现动态改变Windows的显示特性
    Windows常用控件的创建和使用
    如何添加自定义icon
    深入探究VC —— 资源编译器rc.exe(3)
    深入探究VC —— 编译器cl.exe(2)
    gluLookAt()
  • 原文地址:https://www.cnblogs.com/lcw/p/3159508.html
Copyright © 2020-2023  润新知