zoukankan      html  css  js  c++  java
  • linux网络编程之二-----多播(组播)编程

    多播编程实例


    服务器端

    下面是一个多播服务器的例子。多播服务器的程序设计很简单,建立一个数据包套接字,选定多播的IP地址和端口,直接向此多播地址发送数据就可以了。多播服务器的程序设计,不需要服务器加入多播组,可以直接向某个多播组发送数据。

    下面的例子持续向多播IP地址"224.0.0.100"8888端口发送数据"BROADCAST TEST DATA",每发送一次间隔5s

    /*
    *broadcast_server.c - 多播服务程序
    */
    #include <sys/types.h>    
    #include <sys/socket.h>    
    #include <netinet/in.h>    
    #include <arpa/inet.h>    
    #include <time.h>    
    #include <string.h>    
    #include <stdio.h>    
    #include <unistd.h>    
    #include <stdlib.h>
    #define MCAST_PORT 8888
    #define MCAST_ADDR "224.0.0.100"    /*一个局部连接多播地址,路由器不进行转发*/
    #define MCAST_DATA "BROADCAST TEST DATA"            /*多播发送的数据*/
    #define MCAST_INTERVAL 5                            /*发送间隔时间*/
    int main(int argc, char*argv)
    {
        struct sockaddr_in mcast_addr;     
        int fd = socket(AF_INET, SOCK_DGRAM, 0);         /*建立套接字*/
        if (fd == -1)
        {
            perror("socket()");
            exit(1);
        }
       
        memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP多播地址为0*/
        mcast_addr.sin_family = AF_INET;                /*设置协议族类行为AF*/
        mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*设置多播IP地址*/
        mcast_addr.sin_port = htons(MCAST_PORT);        /*设置多播端口*/
       
        /*向多播地址发送数据*/
        while(1) 
    	{
            int n = sendto(fd,MCAST_DATA,sizeof(MCAST_DATA),0,(struct sockaddr*)&mcast_addr,sizeof(mcast_addr)) ;
            if( n < 0)
            {
                perror("sendto()");
                exit(1);
            }      
            sleep(MCAST_INTERVAL);                          /*等待一段时间*/
        }
       
        return 0;
    }


    客户端

    多播组的IP地址为224.0.0.88,端口为8888,当客户端接收到多播的数据后将打印出来。

    客户端只有在加入多播组后才能接受多播组的数据,因此多播客户端在接收多播组的数据之前需要先加入多播组,当接收完毕后要退出多播组。

    /*
    *broadcast_client.c - 多播的客户端
    */
    #include <sys/types.h>    
    #include <sys/socket.h>    
    #include <netinet/in.h>    
    #include <arpa/inet.h>    
    #include <time.h>    
    #include <string.h>    
    #include <stdio.h>    
    #include <unistd.h>    
    #include <stdlib.h>
    #define MCAST_PORT 8888
    #define MCAST_ADDR "224.0.0.100"     /*一个局部连接多播地址,路由器不进行转发*/
    #define MCAST_INTERVAL 5             /*发送间隔时间*/
    #define BUFF_SIZE 256                /*接收缓冲区大小*/
    int main(int argc, char*argv[])
    {  
        struct sockaddr_in local_addr;              /*本地地址*/
       
        int fd = socket(AF_INET, SOCK_DGRAM, 0);     /*建立套接字*/
        if (fd == -1)
        {
            perror("socket()");
            exit(1);
        }  
    	
    	int yes = 1;
    	if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)     
        {    
            perror("Reusing ADDR failed");    
            exit(1);    
        }
       
        /*初始化本地地址*/
        memset(&local_addr, 0, sizeof(local_addr));
        local_addr.sin_family = AF_INET;
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port = htons(MCAST_PORT);
       
        /*绑定socket*/
        int err = bind(fd,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
        if(err < 0)
        {
            perror("bind()");
            exit(1);
        }
       
        /*设置回环许可*/
        int loop = 1;
        err = setsockopt(fd,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));
        if(err < 0)
        {
            perror("setsockopt():IP_MULTICAST_LOOP");
            exit(1);
        }
       
        /*加入多播组*/
        struct ip_mreq mreq;                                    
        mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*多播地址*/
        mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*本地网络接口为默认*/
    	
        /*将本机加入多播组*/
        err = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
        if (err < 0)
        {
            perror("setsockopt():IP_ADD_MEMBERSHIP");
            exit(1);
        }
       
        int times = 0;
        int addr_len = sizeof(local_addr);
        char buff[BUFF_SIZE];
        int n = 0;
    	
        /*循环接收多播组的消息,5次后退出*/
        for(times = 0;times < 5;times++)
        {
            memset(buff, 0, BUFF_SIZE);                 /*清空接收缓冲区*/
    		
            /*接收数据*/
            n = recvfrom(fd, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,&addr_len);
            if( n== -1)
            {
                perror("recvfrom()");
            }
                                                        /*打印信息*/
            printf("Recv %dst message from server:%s
    ", times, buff);
            sleep(MCAST_INTERVAL);
        }
       
        /*退出多播组*/
        err = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));
           
        close(fd);
        return 0;
    }



  • 相关阅读:
    关于路径的小知识点
    转发与重定向
    一种反复的读写文件的方法
    文字排版reportlab
    Qgis中插件的安装位置
    spyder打开文件假死解决
    地图跳跃-超级码力
    尾部的零
    一探torch.nn究竟“What is torch.nn really?”
    KAZE特征和各向异性扩散滤波
  • 原文地址:https://www.cnblogs.com/wangfengju/p/6172357.html
Copyright © 2011-2022 走看看