注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

午夜阳光

 
 
 

日志

 
 

多播  

2011-10-11 13:38:41|  分类: 多播 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
3 多播

 


3.1 多播定义


        多播数据仅由对该数据报感兴趣的接口接收,也就是说,由运行希望参加多播会话应用系统的主机上的接口接收。广播一般局限与局域网,而多播既可用于局域网,也可用于广域网。



3.2 多播地址与以太网地址的映射


        IPV4的D类地址(从224.0.0.0到239.255.255.255)是多播地址。D类地址的低28位构成了多播组ID,而整个32位地址则称为组地址。

        以太网的高序24位总是01:00:5e,下一位总是0,低序23位是多播地址低序23位的拷贝。多播地址的高序5位在映射过程中被忽略。这意味着多个32位多播地址会映射为单个以太网地址,映射不是一对一。
 


3.3 多播帧的过滤过程

        最右边主机绑定123端口,并加入多播组224.0.1.1,告诉数据链路接收以01:00:5e:00:01:01为目的的帧。

        最左边主机向IP地址224.0.1.1及端口123发送数据报。发送主机将帧映射到相应的以太网目的地址,并将帧发送出去。帧中同时包含目的以太网地址(由接口检查)和目的IP地址(由IP层检查)

        中间主机忽略该帧,这是因为:

        (1)帧的目的以太网地址与该主机接口地址不一致。

        (2)帧的目的以太网地址不是广播地址。

        (3)中间主机没有加入一个多播组。

        该帧基于非完备过滤机制被右边的数据链路接收。这是因为我们告诉接口接收以某个具体以太网组地址为目的地址的帧时,它也可能接收以其他以太网地址为目的地址的帧。

        数据链路接收该帧后再传送到IP层。由于该帧的目的地址为多播IP地址,IP层将该分组与我们的应用所加入的多播地址进行比较。如果是自己需要的分组就接收,否则就丢弃。

        IP层继续把该分组传送到UDP层。UDP层将数据报传到绑定123端口的套接口上。这个过程称为完备过滤。


3.4 广域网上的多播

在广域网上5台主机加入一个多播组 

 

在广域网上发送多播数据报


        在左上的局域网上,数据报由发送者多播。接收者H1与MR1接收到了这些数据报。(因为H1加入了这个组,而多播路由器必须接收所有多播数据报)

        MR1将多播数据报转发给MR2,因为多播路由协议告诉MR1,MR2要接收目的地为这个组的数据报。

        MR2向跟它连着的局域网多播此数据报,因为H2、H3属于这个组。MR2也向MR3发送一个数据报的复本。

        MR3向MR4发送多播数据报,但它不在跟自己连着的局域网上多播,因为我们假设在这个局域网上没有主机加入这个组。

        MR4将数据报多播到它所连接的局域网上,因为H4、H5属于这个组。它并不向MR5发送数据报的复本,因为在MR5所连的局域网上没有主机属于这个组,而且MR4根据与MR5交换的多播路由信息已经知道这一点。
3.5 多播代码示例

3.5.1多播套接口选项

        套接口API中增加多播支持内容比较简单:5个套接口选项,其中前2个选项影响到多播数据报的接收,后 3个选项影响到多播UDP数据报的发送。3.5.2多播库封装

代码如下:


多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 本地接口local_if加入多播组mcaddr
多播 - 小妮子 - 午夜阳光int mcast_join(SOCKET s,struct in_addr *mcaddr, struct in_addr *local_if)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    struct ip_mreq mreq;
多播 - 小妮子 - 午夜阳光    memcpy(&(mreq.imr_interface), local_if, sizeof(struct in_addr)); // local if
多播 - 小妮子 - 午夜阳光    memcpy(&(mreq.imr_multiaddr), mcaddr, sizeof(struct in_addr));  // mutilcast group address
多播 - 小妮子 - 午夜阳光    return (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 本地接口local_if离开多播组
多播 - 小妮子 - 午夜阳光int mcast_leave(SOCKET s, struct in_addr *mcaddr, struct in_addr *local_if)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    struct ip_mreq mreq;
多播 - 小妮子 - 午夜阳光    memcpy(&(mreq.imr_interface), local_if, sizeof(struct in_addr)); // local if
多播 - 小妮子 - 午夜阳光    memcpy(&(mreq.imr_multiaddr), local_if, sizeof(struct in_addr)); // mutilcast group address
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    return (setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mreq, sizeof(mreq)));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 为多播报文设置外出接口
多播 - 小妮子 - 午夜阳光int mcast_set_if(SOCKET s, const DWORD local_out_if)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    return (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_out_if, 
多播 - 小妮子 - 午夜阳光        sizeof(local_out_if)));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 获取多播报文的外出接口
多播 - 小妮子 - 午夜阳光int mcast_get_if(SOCKET s, DWORD *local_out_if)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    int len = sizeof(DWORD);
多播 - 小妮子 - 午夜阳光    return (getsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&local_out_if, &len));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 设置外出多播报文的ttl值,默认为1
多播 - 小妮子 - 午夜阳光int mcast_set_ttl(SOCKET s, const DWORD ttl)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    return (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 获取外出多播报文的ttl值
多播 - 小妮子 - 午夜阳光int mcast_get_ttl(SOCKET s, DWORD *ttl)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    int len = sizeof(DWORD);
多播 - 小妮子 - 午夜阳光    return (getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)ttl, &len));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 启用或者禁止多播报文环回
多播 - 小妮子 - 午夜阳光int mcast_set_loop(SOCKET s, const BOOL flag)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    return (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&flag, sizeof(flag)));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光// 获取本地多播回环状态
多播 - 小妮子 - 午夜阳光int mcast_get_loop(SOCKET s, BOOL *flag)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    int len = sizeof(BOOL);
多播 - 小妮子 - 午夜阳光    return (getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)flag, &len));
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光
3.5.3多播例子


发送端:

 


多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光#pragma comment(lib,"ws2_32.lib")
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光#include <stdio.h>
多播 - 小妮子 - 午夜阳光#include <WINSOCK2.H>
多播 - 小妮子 - 午夜阳光#include "mcastlib.h"
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光//#define ERR_EXIT(m) (perror(m),exit(EXIT_FAILURE))
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光#define MCAST_PORT 5000
多播 - 小妮子 - 午夜阳光#define MCAST_IP "224.0.0.99"
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光void main(int argc, char* argv[])
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    SOCKET sockfd;
多播 - 小妮子 - 午夜阳光    struct sockaddr_in mcastaddr;
多播 - 小妮子 - 午夜阳光    char buf[] = "this is a test message";
多播 - 小妮子 - 午夜阳光    int addrlen;
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    WORD wVersionRequested;
多播 - 小妮子 - 午夜阳光    WSADATA wsaData;
多播 - 小妮子 - 午夜阳光    int err;
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    wVersionRequested = MAKEWORD( 2, 2 );
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    err = WSAStartup( wVersionRequested, &wsaData );
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    if ( err != 0 ) 多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* Tell the user that we could not find a usable */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* WinSock DLL.                                  */
多播 - 小妮子 - 午夜阳光        return;
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* Confirm that the WinSock DLL supports 2.2.*/
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* Note that if the DLL supports versions greater    */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* than 2.2 in addition to 2.2, it will still return */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* 2.2 in wVersion since that is the version we      */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* requested.                                        */
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    if ( LOBYTE( wsaData.wVersion ) != 2 ||
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        HIBYTE( wsaData.wVersion ) != 2 ) 多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* Tell the user that we could not find a usable */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* WinSock DLL.                                  */
多播 - 小妮子 - 午夜阳光        WSACleanup( );
多播 - 小妮子 - 午夜阳光        return; 
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    sockfd = socket(AF_INET,SOCK_DGRAM,0);
多播 - 小妮子 - 午夜阳光    //if (sockfd < 0)
多播 - 小妮子 - 午夜阳光    //    ERR_EXIT("socket");
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    memset(&mcastaddr,0,sizeof(mcastaddr));
多播 - 小妮子 - 午夜阳光    mcastaddr.sin_family = AF_INET;
多播 - 小妮子 - 午夜阳光    mcastaddr.sin_addr.s_addr = inet_addr(MCAST_IP);
多播 - 小妮子 - 午夜阳光    mcastaddr.sin_port = htons(MCAST_PORT);
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    addrlen = sizeof(mcastaddr);
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//*
多播 - 小妮子 - 午夜阳光    // 获取默认的多播报文TTL值和环回状态
多播 - 小妮子 - 午夜阳光    DWORD ttl;
多播 - 小妮子 - 午夜阳光    if (mcast_get_ttl(sockfd, &ttl) == SOCKET_ERROR){
多播 - 小妮子 - 午夜阳光        printf("mcast_get_ttl: %d\n",WSAGetLastError());
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    BOOL loop;
多播 - 小妮子 - 午夜阳光    if (mcast_get_loop(sockfd, &loop) == SOCKET_ERROR){
多播 - 小妮子 - 午夜阳光        printf("mcast_get_loop: %d\n", WSAGetLastError());
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    printf("multicast default: TTL = %d, LoopBack = %d\n", ttl, loop);
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    // 设置ttl值为219
多播 - 小妮子 - 午夜阳光    ttl = 219;
多播 - 小妮子 - 午夜阳光    if (mcast_set_ttl(sockfd, ttl) == SOCKET_ERROR){
多播 - 小妮子 - 午夜阳光        printf("mcast_set_ttl: %d\n", WSAGetLastError());
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    // 如果需要,设置外出接口
多播 - 小妮子 - 午夜阳光    if (mcast_set_if(sockfd,inet_addr("172.16.253.26")) == SOCKET_ERROR)
多播 - 小妮子 - 午夜阳光    {
多播 - 小妮子 - 午夜阳光        printf("mcast_set_if: %d\n", WSAGetLastError());
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    */
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    int ret;
多播 - 小妮子 - 午夜阳光    while (1)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光        ret = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&mcastaddr,addrlen);
多播 - 小妮子 - 午夜阳光        //if (ret < 0)
多播 - 小妮子 - 午夜阳光        //    ERR_EXIT("sendto");
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光        printf("send to %s:%u\n",inet_ntoa(mcastaddr.sin_addr),ntohs(mcastaddr.sin_port));
多播 - 小妮子 - 午夜阳光        Sleep(2000);
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光

 

 

接收端:

 


多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光#pragma comment(lib,"ws2_32.lib")
多播 - 小妮子 - 午夜阳光#include <stdio.h>
多播 - 小妮子 - 午夜阳光#include <WINSOCK2.H>
多播 - 小妮子 - 午夜阳光#include "mcastlib.h"
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光#define MCAST_PORT 5000
多播 - 小妮子 - 午夜阳光#define MCAST_IP "224.0.0.99"
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光void main(int argc, char* argv[])
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光    SOCKET sockfd;
多播 - 小妮子 - 午夜阳光    struct sockaddr_in localaddr;
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    char buf[1024] = 多播 - 小妮子 - 午夜阳光{0};
多播 - 小妮子 - 午夜阳光    int addrlen;
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    WORD wVersionRequested;
多播 - 小妮子 - 午夜阳光    WSADATA wsaData;
多播 - 小妮子 - 午夜阳光    int err;
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    wVersionRequested = MAKEWORD( 2, 2 );
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    err = WSAStartup( wVersionRequested, &wsaData );
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    if ( err != 0 ) 多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* Tell the user that we could not find a usable */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* WinSock DLL.                                  */
多播 - 小妮子 - 午夜阳光        return;
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* Confirm that the WinSock DLL supports 2.2.*/
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* Note that if the DLL supports versions greater    */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* than 2.2 in addition to 2.2, it will still return */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* 2.2 in wVersion since that is the version we      */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//* requested.                                        */
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    if ( LOBYTE( wsaData.wVersion ) != 2 ||
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        HIBYTE( wsaData.wVersion ) != 2 ) 多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* Tell the user that we could not find a usable */
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光        /**//* WinSock DLL.                                  */
多播 - 小妮子 - 午夜阳光        WSACleanup( );
多播 - 小妮子 - 午夜阳光        return; 
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    sockfd = socket(AF_INET,SOCK_DGRAM,0);
多播 - 小妮子 - 午夜阳光    //if (sockfd < 0)
多播 - 小妮子 - 午夜阳光    //    ERR_EXIT("socket");
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    // 设置本地地址
多播 - 小妮子 - 午夜阳光    memset(&localaddr,0,sizeof(localaddr));
多播 - 小妮子 - 午夜阳光    localaddr.sin_family = AF_INET;
多播 - 小妮子 - 午夜阳光    localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
多播 - 小妮子 - 午夜阳光    localaddr.sin_port = htons(MCAST_PORT);
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    addrlen = sizeof(localaddr);
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    int opt = 1;
多播 - 小妮子 - 午夜阳光    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&opt,sizeof(opt));
多播 - 小妮子 - 午夜阳光    //if (ret < 0)
多播 - 小妮子 - 午夜阳光    //    ERR_EXIT("setsockopt");
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    ret = bind(sockfd,(struct sockaddr *)&localaddr, sizeof(localaddr));
多播 - 小妮子 - 午夜阳光    //if (ret < 0)
多播 - 小妮子 - 午夜阳光    //    ERR_EXIT("setsockopt");
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//*
多播 - 小妮子 - 午夜阳光    // 设置ipmr结构
多播 - 小妮子 - 午夜阳光    struct ip_mreq ipmr;
多播 - 小妮子 - 午夜阳光    memset((void*)&ipmr, 0, sizeof(ipmr));
多播 - 小妮子 - 午夜阳光    ipmr.imr_multiaddr.s_addr = inet_addr(MCAST_IP);
多播 - 小妮子 - 午夜阳光    ipmr.imr_interface.s_addr = htonl(INADDR_ANY);
多播 - 小妮子 - 午夜阳光    // 加入到多播组
多播 - 小妮子 - 午夜阳光    setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(const char*)&ipmr,sizeof(ipmr));
多播 - 小妮子 - 午夜阳光    //if (ret < 0)
多播 - 小妮子 - 午夜阳光    //    ERR_EXIT("setsockopt");
多播 - 小妮子 - 午夜阳光    */
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    struct in_addr mcastaddr;
多播 - 小妮子 - 午夜阳光    mcastaddr.s_addr = inet_addr(MCAST_IP);
多播 - 小妮子 - 午夜阳光    if (mcast_join(sockfd, &mcastaddr, &(localaddr.sin_addr)) == SOCKET_ERROR)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光        printf("Join Multicast Group: %d\n", WSAGetLastError());
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光    while (1)
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    多播 - 小妮子 - 午夜阳光{
多播 - 小妮子 - 午夜阳光        ret = recvfrom(sockfd,buf,1024,0,(struct sockaddr *)&localaddr,&addrlen);
多播 - 小妮子 - 午夜阳光    //    if (ret < 0)
多播 - 小妮子 - 午夜阳光    //        ERR_EXIT("recvfrom");
多播 - 小妮子 - 午夜阳光        buf[ret] = '\0';
多播 - 小妮子 - 午夜阳光        printf("receive from %s:%u\n",inet_ntoa(localaddr.sin_addr),ntohs(localaddr.sin_port));
多播 - 小妮子 - 午夜阳光        printf("\tpacket data: %s\n", buf);
多播 - 小妮子 - 午夜阳光    }
多播 - 小妮子 - 午夜阳光
多播 - 小妮子 - 午夜阳光多播 - 小妮子 - 午夜阳光    /**//*
多播 - 小妮子 - 午夜阳光    // 退出多播组
多播 - 小妮子 - 午夜阳光    ret = setsockopt(sockfd,IPPROTO_IP,IP_DROP_MEMBERSHIP,(const char*)&ipmr,sizeof(ipmr));
多播 - 小妮子 - 午夜阳光    //if (ret < 0)
多播 - 小妮子 - 午夜阳光    //        ERR_EXIT("setsockopt");
多播 - 小妮子 - 午夜阳光    */
多播 - 小妮子 - 午夜阳光    mcast_leave(sockfd,&mcastaddr,&localaddr.sin_addr);
多播 - 小妮子 - 午夜阳光    
多播 - 小妮子 - 午夜阳光    closesocket(sockfd);
多播 - 小妮子 - 午夜阳光}
多播 - 小妮子 - 午夜阳光

 

  评论这张
 
阅读(476)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018