广域网组播的例子,没试过不知道行不行

Here are some trivial examples of working SSM code. They certainly work under LinuxKernel2.6, and have been tested on amd64 in Gentoo and on ia32 DebianLinux. It's possible that SSM is not supported in Linux 2.4. The examples join the SSM group ip-of-sender, 232.1.1.1. In a real application you should randomly select the 232.0.0.0/8 address at runtime to avoid conflicts.

Note that some information is included in #ifndefs since many LinuxDistributions don't install the required header files yet.

I had one major problem while trying to debug this. My mistake was that the reciever wasn't binding to INADDR_ANY for the listening socket, but instead to an IP address on the machine. This caused all the multicast packets to be ignored. Oops.

Another bug was due to the server using the SSM source of the unassigned address. Oops.

Sender:
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>

/* Not everyone has the headers for this so improvise */
#ifndef MCAST_JOIN_SOURCE_GROUP
#define MCAST_JOIN_SOURCE_GROUP 46

struct group_source_req
{
        /* Interface index.  */
        uint32_t gsr_interface;

        /* Group address.  */
        struct sockaddr_storage gsr_group;

        /* Source address.  */
        struct sockaddr_storage gsr_source;
};
#endif

int main(int argc, char *argv[])
{
        struct group_source_req group_source_req;
        struct sockaddr_in *group;
        struct sockaddr_in *source;
        int fd = socket(AF_INET,SOCK_DGRAM,getprotobyname("udp")->p_proto);
        socklen_t socklen = sizeof(struct sockaddr_storage);
        struct sockaddr_in bindaddr;
        u_char loop = 1;

        /* First bind to the port */
        bindaddr.sin_family = AF_INET;
        bindaddr.sin_port = htons(9990);
        bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);

        bind(fd,(struct sockaddr*)&bindaddr,sizeof(bindaddr));
        /* Now set up the SSM request */
        group_source_req.gsr_interface = 0; /* "any" interface */
        group=(struct sockaddr_in*)&group_source_req.gsr_group;
        source=(struct sockaddr_in*)&group_source_req.gsr_source;

        group->sin_family = AF_INET;
        inet_aton("232.1.1.1",&group->sin_addr);
        group->sin_port = 0;    /* Ignored */

        /* Set the source to the name of the socket we created above */
        getsockname(fd,(struct sockaddr *)source, &socklen);

        setsockopt(fd,SOL_IP,MCAST_JOIN_SOURCE_GROUP, &group_source_req,
                                sizeof(group_source_req));

        /* Enable reception of our own multicast */
        loop = 1;
        setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
        /* Set the TTL on packets to 250 */
        loop=250;
        setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &loop, sizeof(loop));
        /* Now we care about the port we send to */
        group->sin_port = htons(9991);

        /* Now send packets */
        while(1) {
                sendto(fd,"Hello World",strlen("Hello World"),0,
                        (struct sockaddr*)group,sizeof(struct sockaddr_in));
                sleep(1);
        }
        return 0;
}
Receiver:

Pass the IP address of the sender as CommandLine argument: ./ssm-rec ip.address.of.sender

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>

/* Not everyone has the headers for this, so improvise */
#ifndef MCAST_JOIN_SOURCE_GROUP
#define MCAST_JOIN_SOURCE_GROUP 46

struct group_source_req
{
        /* Interface index.  */
        uint32_t gsr_interface;

        /* Group address.  */
        struct sockaddr_storage gsr_group;

        /* Source address.  */
        struct sockaddr_storage gsr_source;
};
#endif

int main(int argc, char *argv[])
{
        struct group_source_req group_source_req;
        struct sockaddr_in *group;
        struct sockaddr_in *source;
        int fd = socket(AF_INET,SOCK_DGRAM,getprotobyname("udp")->p_proto);
        struct sockaddr_in bindaddr;

        /* Setup the socket to listen on */
        bindaddr.sin_family = AF_INET;
        bindaddr.sin_port = htons(9991);
        bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        bind(fd,(struct sockaddr*)&bindaddr,sizeof(bindaddr));

        /* Set up the connection to the group */
        group_source_req.gsr_interface = 0;
        group=(struct sockaddr_in*)&group_source_req.gsr_group;
        source=(struct sockaddr_in*)&group_source_req.gsr_source;
        /* Group is 232.1.1.1 */
        group->sin_family = AF_INET;
        inet_aton("232.1.1.1",&group->sin_addr);
        group->sin_port = 0;

        /* Source is 10.1.20.9 */
        source->sin_family = AF_INET;
        inet_aton(argv[1],&source->sin_addr);
        source->sin_port = 0;

        setsockopt(fd,SOL_IP,MCAST_JOIN_SOURCE_GROUP, &group_source_req,
                                sizeof(group_source_req));

        while(1) {
                char buffer[65536];
                int ret=recv(fd,(char*)buffer,sizeof(buffer),0);
                write(1,buffer,ret);
        }
        return 0;
}
Python:
#! /usr/bin/python

import getopt
import socket
import sys

if not hasattr(socket, 'IP_MULTICAST_TTL'):
  setattr(socket, 'IP_MULTICAST_TTL', 33)
if not hasattr(socket, 'IP_ADD_SOURCE_MEMBERSHIP'):
  setattr(socket, 'IP_ADD_SOURCE_MEMBERSHIP', 39)

if sys.argv[1] == 'send':
  opts, args = getopt.getopt(sys.argv[2:], 't:s:g:p:')
  opts = dict(opts)

  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  if '-t' in opts:
    s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, chr(int(opts['-t'])))
  if '-s' in opts:
    s.bind((opts['-s'], 0))
  s.connect((opts['-g'], int(opts['-p'])))
  print 'READY.'
  while True:
    s.send(sys.stdin.readline())

elif sys.argv[1] == 'recv':
  opts, args = getopt.getopt(sys.argv[2:], 'g:i:s:p:')
  opts = dict(opts)
  opts.setdefault('-i', '0.0.0.0')

  imr = (socket.inet_pton(socket.AF_INET, opts['-g']) +
         socket.inet_pton(socket.AF_INET, opts['-i']) +
         socket.inet_pton(socket.AF_INET, opts['-s']))

  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  s.setsockopt(socket.SOL_IP, socket.IP_ADD_SOURCE_MEMBERSHIP, imr)
  s.bind((opts['-g'], int(opts['-p'])))
  print 'READY.'
  while True:
    print repr(s.recvfrom(4096))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值