通过sendto()的UDP广播返回;Can';t分配请求的地址“;在OS/X上,而不是Linux上

通过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

我正在尝试使用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");
}
如果我像这样运行上面的代码:

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——所以我很惊讶你的程序能工作