gpt4 book ai didi

linux - 通过 sendto() 的 UDP 广播返回 "Can' t assign requested address"on OS/X but not Linux

转载 作者:太空狗 更新时间:2023-10-29 11:13:07 24 4
gpt4 key购买 nike

我正在尝试使用 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*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");
}

我的 OS/X 机器在本地网络上,IP 地址为 192.168.0.4,广播地址为 192.168.0.255ifconfig en1 | 的输出grep broadcast 产生以下内容:

inet 192.168.0.4 netmask 0xffffff00 broadcast 192.168.0.255

如果我像这样运行上面的代码:

a.out 192.168.0.255 1234

bind()setsockopt() 函数有效,但 sendto() 返回 errno 49。我的程序打印以下内容:

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 上不起作用)。

知道 Apple 在这里做什么吗?

最佳答案

看起来 linux 的限制较少。问题应该是尝试绑定(bind)到非本地地址 192.168.0.255:

sock_in.sin_addr.s_addr=inet_addr(bcast_addr);

为什么不使用 0.0.0.0 或 127.0.0.1 作为源地址?或者,如果您只想绑定(bind)到特定接口(interface),您可以使用例如处理有关网络地址和网络掩码的信息。 getifaddrs/freeifaddrs.

关于linux - 通过 sendto() 的 UDP 广播返回 "Can' t assign requested address"on OS/X but not Linux,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33072128/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com