通过sendto()的UDP广播返回;Can';t分配请求的地址“;在OS/X上,而不是Linux上
我正在尝试使用sendto()函数通过UDP广播字符串 下面的代码在Linux机器(例如Raspberry Pi)上运行良好,但在iMac和MacBook Air上的OS/X下运行失败通过sendto()的UDP广播返回;Can';t分配请求的地址“;在OS/X上,而不是Linux上,linux,macos,sockets,udp,Linux,Macos,Sockets,Udp,我正在尝试使用sendto()函数通过UDP广播字符串 下面的代码在Linux机器(例如Raspberry Pi)上运行良好,但在iMac和MacBook Air上的OS/X下运行失败 #include <stdio.h> #include <arpa/inet.h> #include <string.h> #include <errno.h> #include <stdlib.h> int main(int argc, char*a
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char*argv[])
{
const char *msg_str = "hello, world";
const char *bcast_addr = argv[1];
int port = atoi(argv[2]);
struct sockaddr_in sock_in;
int yes = 1;
int sinlen = sizeof(struct sockaddr_in);
memset(&sock_in, 0, sinlen);
int sock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if ( sock < 0 ) {
printf("socket: %d %s\n", errno, strerror(errno));
exit(-1);
}
sock_in.sin_addr.s_addr=inet_addr(bcast_addr);
sock_in.sin_port = htons(port);
sock_in.sin_family = PF_INET;
if ( bind(sock, (struct sockaddr *)&sock_in, sinlen) < 0 ) {
printf("bind: %s %d %s\n", bcast_addr, errno, strerror(errno));
exit(-1);
}
if ( setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(int) ) < 0 ) {
printf("setsockopt: %d %s\n", errno, strerror(errno));
exit(-1);
}
if ( sendto(sock, msg_str, strlen(msg_str), 0, (struct sockaddr *)&sock_in, sinlen) < 0 ) {
printf("sendto: %d %s str='%s', sinlen=%d\n", errno, strerror(errno), msg_str, sinlen);
exit(-1);
}
printf("message sent!\n");
}
如果我像这样运行上面的代码:
a.out 192.168.0.255 1234
bind()
和setsockopt()
函数工作,但sendto()
返回errno 49
。我的程序打印以下内容:
inet 192.168.0.4 netmask 0xffffff00 broadcast 192.168.0.255
sendto: 49 Can't assign requested address str='hello, world', sinlen=16
但如果我像这样运行它:
a.out 192.168.0.4 1234
然后一切正常。当然,广播只会传到当地的电视台
当我在同一网络上的Linux设备上使用广播地址(例如,192.168.0.255
)时,它工作正常。在我的Mac电脑上,我尝试以普通用户和root用户的身份运行,结果相同。我似乎记得这在几个版本的OS/X上都能工作(我知道它在Mavericks上不起作用)
知道苹果在这里做什么吗 看起来linux的限制性要小一些。问题应该是试图绑定到非本地地址192.168.0.255:
sock_in.sin_addr.s_addr=inet_addr(bcast_addr);
为什么不使用0.0.0.0或127.0.0.1作为源地址?
或者,如果您只想绑定到特定接口,您可以使用例如getifaddrs/freeifaddrs来处理有关网络地址和网络掩码的信息。
我需要地址192.168.0.255,因为我希望消息在整个本地子网中广播
但是我
y\u ug
是正确的——问题在于对非本地地址调用bind()
。我根本不需要那个电话,因为我所做的就是发送。事实上,这毫无意义——我一定是从其他代码中复制的。出于某种原因,Raspberry Pi(运行Debian Linux)似乎并不介意,而且工作正常。但是OS/X框给出了上述错误 UDP通道处于更高的范围内。有效的多播地址范围从224.0.0.1到239.255.255.255——所以我很惊讶你的程序能工作