LCM可以通过组播方式发送数据,但是在Linux操作系统上,多网卡的电脑上,应用LCM的程序总是自动绑定其他的网卡上,不是我们想要通信的那个网卡。
1、查看LCM的源码,看它是如何绑定的,
lcm_udpm.c 文件中 lcm_provider_t * lcm_udpm_create (lcm_t * parent, const char *network, const GHashTable *args)
SOCKET testfd = socket (AF_INET, SOCK_DGRAM, 0); 创建socket,连接socket
lcm->sendfd = socket (AF_INET, SOCK_DGRAM, 0);
setsockopt (lcm->sendfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) ¶ms.mc_ttl, sizeof (params.mc_ttl)) ;
setsockopt (lcm->sendfd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &send_lo_opt, sizeof (send_lo_opt)) ;
struct ip_mreq mreq;
mreq.imr_multiaddr = lcm->params.mc_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt (lcm->sendfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof (mreq)) ;
2、UDP组播
将IP加到组播组,成为一个或多个IP组播组的成员,这样就可以接收IP组播数据报文。
使用了参数是mreq,“mreq”是一个这样的结构:
struct ip_mreq
{
struct in_addr imr_multiaddr; /* multicast group to join */
struct in_addr imr_interface; /* interface to join on */
}
imr_interface 是INADDR_ANY时,可以使得多个网卡同时加入多播组,多个网卡都可以接收到组播的数据报文,但是没法在指定的网卡上发送数据,因为以这种方式加入多播发送数据的时候操作系统总以默认的网卡发送数据,系统如果默认的网卡不是自己期望的那个网卡,数据就发送不成功。
临时修改:sudo route add default gw **.**.*.1 ,每次重启电脑就需要重新设置;
永久修改:不同的操作系统修改默认网关不一样,可以自行百度搜索。
2. 重写LCM的底层接口,改成固定绑定,指定某个网卡(具有多播能力的)对应的IP。
另外,需要注意的是,如果每个网卡都要求发送数据,那么每个网卡都需要绑定,同一个组播里面的最大成员数不超过20。
struct ip_mreq mcast;
mcast.imr_multiaddr.s_addr = inet_addr(MCASTADDR);
mcast.imr_interface.s_addr = inet_addr("192.168.10.164");
setsockopt(sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast))
附一篇讲解UDP绑定接口很好的文章
http://www.kohala.com/start/mcast.api.txt