#include #include "my_inet.h"
#define MAXBUF 256
#define PUERTO 5000
#define GROUP "224.0.1.1"
int main(void)
{
int fd;
struct sockaddr_in srv,local;
struct in_addr if_req;
char buf[MAXBUF];
srv.sin_family = MY_AF_INET;
srv.sin_port = htons(PUERTO);
inet_aton(GROUP, &srv.sin_addr);
local.sin_family =MY_ AF_INET;
local.sin_port = htons(16000);
inet_aton(GROUP, &(local.sin_addr) );
if( (fd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 ){
perror("socket");
return -1;
}
if( bind( fd, (struct sockaddr *)&local, sizeof(local) ) < 0 ){
perror("bind:");
return -1;
}
inet_aton("172.16.48.2", &(if_req) );
if( setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &if_req, sizeof(struct in_addr) ) < 0 ){
perror("setsockopt:");
return -1;
}
while( fgets(buf, MAXBUF, stdin) ){
if( sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&srv, sizeof(srv)) < 0 ){
perror("sendto");
}else{
fprintf(stdout, "Enviado a %s: %s", GROUP, buf);
}
}
}
这回,本地套接口被绑定在了一个组播地址上了,这样,这个应用程序不仅能够发送组播数据,也能够接受同组中发往16000端口的数据报了(最好再加个IP_ADD_MEMBERSHIP选项的操作),但bind组播地址时,只会设定接收地址为该组播地址,不会设定发送源地址,所以,必须使用IP_MULTICAST_IF接口指定一个发送接口(程序中指定了172.16.48.2,即eth0接口)。
这两个程序在现在的my_inet模块中均能够正常工作,但是它们调用的实际发送代码是UDP单播的代码,这基本能正常工作,但是单播的代码少了很多对组播的特殊处理,比如组播路由验证,环路发送等。
在下一篇,我们将为模块添加组播数据报发送的代码,并给出分析。
注:严格来讲,上述两个程序都是有问题的,程序1的套接口会收到发往本机172.16.48.2接口的16000端口的数据,并阻塞在套接口的接收队列中,程序2会收到发往组224.0.1.1的16000端口的数据,并阻塞在套接口的接收队列中。