问题描述
我有一个发送多播数据报的代码.一段关键的代码:
I have a code in which send multicast datagrams.A critical piece of code:
uint32_t port;
int sockfd, err_ip;
const uint32_t sizebuff = 65535 - (20 + 8);
unsigned char *buff = (unsigned char *) malloc(sizebuff);
struct sockaddr_in servaddr, cliaddr;
struct in_addr serv_in_addr;
struct ip_mreq req;
port = str2uint16(cmdsrv->ipport);
bzero(buff, (size_t)sizebuff);
bzero(&servaddr, sizeof(servaddr));
bzero(&serv_in_addr, sizeof(serv_in_addr));
err_ip = inet_aton(cmdsrv->ipaddr, &serv_in_addr);
if(( err_ip != 0 ) && ( port != 0 )) {
servaddr.sin_family = AF_INET;
servaddr.sin_addr = serv_in_addr;
servaddr.sin_port = htons(port);
memcpy(&req.imr_multiaddr,&serv_in_addr,sizeof(req.imr_multiaddr));
req.imr_interface.s_addr = INADDR_ANY;
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if( sockfd == -1 ) {
int outerror = errno;
char *retstr = "Couldn't open socket
";
pthread_exit(retstr);
}
else {
struct in_addr ifaddr;
ifaddr.s_addr = INADDR_ANY;
int optres3 =
setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
sizeof( ifaddr ));
if( optres3 == -1 ) {
int perrno = errno;
char *retstr = "Can't set IP_MULTICAST_IF for socket
";
printf( "Error setsockopt: ERRNO = %s
", strerror( perrno ));
printf( "%s",retstr );
pthread_exit(retstr);
}
unsigned char ttl = 32;
int optres2 =
setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof( ttl ));
if( optres2 == -1 ) {
int perrno = errno;
char *retstr = "Can't set IP_MULTICAST_TTL for socket
";
printf("Error setsockopt: ERRNO = %s
",strerror(perrno));
printf("%s",retstr);
pthread_exit(retstr);
}
int optres =
setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
sizeof( req ));
if( optres == -1 ) {
int perrno = errno;
char *retstr = "Can't join to multicast-group
";
printf("Error setsockopt: ERRNO = %s
",strerror(perrno));
printf("%s",retstr);
pthread_exit(retstr);
}
// Bind port with socket
uint16_t cliport;
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = INADDR_ANY;
if( strcmp( cmdsrv->ipport, "16011" ) == 0 ) {
cliport = str2uint16("16003");
cliaddr.sin_port = htons(cliport);
}
else if( strcmp( cmdsrv->ipport, "16012" ) == 0 ) {
cliport = str2uint16("16004");
cliaddr.sin_port = htons(cliport);
}
else {
printf("Device hasn't such port");
pthread_exit(NULL);
}
int bindres =
bind( sockfd, (struct sockaddr*)&cliaddr, sizeof( cliaddr ));
if( bindres == -1 ) {
int perrno = errno;
perror("Error in bind
");
}
// ADD 1 BYTE
data rawdata;
rawdata.desc = 23;
printf( "SIZEOF = %d
", sizeof( *( cmdsrv->cmd )));
memcpy( &rawdata.cmd, cmdsrv->cmd, sizeof( *( cmdsrv->cmd )));
printf( "RAWDATA: desc = %d, cmd = %d
", rawdata.desc, rawdata.cmd );
int outerror = 0;
printf( "Send command to IP:
addr = %s, port = %d
",
inet_ntoa( servaddr.sin_addr ), ntohs( servaddr.sin_port ));
int size = sendto( sockfd, &rawdata, sizeof( rawdata ), 0,
(struct sockaddr*)&servaddr, sizeof( servaddr ));
if( size == -1 ) {
perror("Can't send command to socket");
}
...
有时程序会成功执行(此时我有 IP - 192.168.80.122
).我可以通过wireshark 捕获我的多播数据报.没关系.
Sometimes program executes successfully (at this moment I have IP - 192.168.80.122
). I can capture my multicast datagram by wireshark. That's all OK.
但是如果我将我的 IP 更改为 192.168.1.2
,调用时会出错
But if I change my IP to 192.168.1.2
, I get error when is called
int optres =
setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req,
sizeof( req ));
而且我什至无法捕获我的多播数据包.什么都没有发送.哪里出问题了?
And I can't even capture my multicast packet. Nothing is sent.Where's bug?
推荐答案
如果它适用于一个 IP 但不适用于另一个 IP,也许 这个可以提供帮助.
If it works for one IP but not for another, maybe this can help.
这意味着该工具正在尝试使用多播,但网络接口不支持它.可能有两个原因:
您的机器未启用多播支持.例如,在 Linux 和 FreeBSD 上,可以编译不支持多播的内核.
Your machine doesn't have multicast support enabled. For example, on Linux and FreeBSD it is possible to compile a kernel which doesn't support multicast.
您没有多播流量的路由.有的系统默认不加这个,需要自己运行.route add -net 224.0.0.0 netmask 224.0.0.0 eth0
(或类似).如果您希望仅在单播模式下使用 RAT,可以在环回接口上添加多播路由.
You don't have a route for multicast traffic. Some systems don't add this by default, and you need to run. route add -net 224.0.0.0 netmask 224.0.0.0 eth0
(or similar). If you wish to use RAT in unicast mode only, it is possible to add the multicast route on the loopback interface.
这篇关于错误“没有这样的设备"在加入多播组时调用 setsockopt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!