【发布时间】:2010-06-24 11:56:22
【问题描述】:
我已经建立了一个 udp 服务器,它每隔一段时间就会广播一条消息。它广播没有问题。但是如果我打开我的 vpn,即使我正在发送到 INADDR_BROADCAST,sendto 也会开始返回 -1。
如果这有什么改变,我会在 mac 上运行它。我真的不知道为什么会发生这种情况,我真的很想知道 udp 广播怎么会失败?
【问题讨论】:
我已经建立了一个 udp 服务器,它每隔一段时间就会广播一条消息。它广播没有问题。但是如果我打开我的 vpn,即使我正在发送到 INADDR_BROADCAST,sendto 也会开始返回 -1。
如果这有什么改变,我会在 mac 上运行它。我真的不知道为什么会发生这种情况,我真的很想知道 udp 广播怎么会失败?
【问题讨论】:
您应该检查 errno 全局变量以获得更详细的错误描述。在sendto(2) 手册页的错误部分中描述了此调用的可能值。
例如:
[EACCES] 套接字上没有设置 SO_BROADCAST 选项,并且给出了一个广播地址作为目标。
[EHOSTUNREACH] 目标地址指定了一个无法访问的主机。
[ENETUNREACH] 不存在到网络的路由。
【讨论】:
我的 errno 是 227(我认为)
sendto: 无法分配请求的地址
我认为打开我的 vpn 时它找不到广播端口,这是我打开我的 vpn 并关闭它时的示例
2010-06-25 04:05:55.022 SwypeSendForMac2[63687:6203] 向 socked 6 写入了 187 个字节 2010-06-25 04:05:56.023 SwypeSendForMac2[63687:6203] 写了 187 个字节到 socked 6 2010-06-25 04:05:57.024 SwypeSendForMac2[63687:6203] 写了 187 个字节到 socked 6 sendto:无法分配请求的地址 sendto:无法分配请求的地址 sendto:无法分配请求的地址 sendto:无法分配请求的地址 sendto:无法分配请求的地址 sendto:无法分配请求的地址 sendto:无法分配请求的地址 2010-06-25 04:06:05.027 SwypeSendForMac2[63687:6203] 向 socked 6 写入了 187 个字节 2010-06-25 04:06:06.031 SwypeSendForMac2[63687:6203] 向 socked 6 写入 187 个字节
中间当然是开启vpn
这是我的路由表没有 vpn:
34:~ samuelw$ netstat -r 路由表
互联网: 目标网关标志 Refs 使用 Netif 过期 默认 192.168.1.1 UGSc 63 0 en1 127 本地主机 UCS 0 0 lo0 本地主机本地主机 UH 1 180317 lo0 169.254 链接#5 UCS 1 0 en1 cronos.local 链接#5 UHLW 0 1 en1 192.168.1 链接#5 UCS 4 0 en1 192.168.1.1 90:84:d:d3:e2:54 UHLWI 69 1260 en1 1123 192.168.1.98 0:11:24:a2:41:6d UHLWI 0 324 en1 1112 192.168.1.152 0:21:e9:76:fe:6b UHLWI 0 0 en1 657 192.168.1.153 本地主机 UHS 0 118 lo0 192.168.1.154 0:21:5c:52:e0:11 UHLWI 1 2662 en1 1134
互联网6: 目标网关标志 Netif 过期 本地主机 本地主机 UH lo0 fe80::%lo0 本地主机 Uc lo0 本地主机链接#1 UHL lo0 fe80::%en1 链接#5 UC en1 samuelmacbook.loca 0:1e:c2:a6:64:98 UHL lo0 cronos.local 0:21:5c:52:e0:11 UHLW en1 ff01:: 本地主机嗯 lo0 ff02:: 本地主机 UmC lo0 ff02:: 链接#5 UmC en1
和我的 vpn
34:~ samuelw$ netstat -r 路由表
互联网: 目标网关标志 Refs 使用 Netif 过期 默认 172.16.20.1 UGSc 8 0 ppp0 默认 192.168.1.1 UGScI 1 0 en1 127 本地主机 UCS 0 0 lo0 本地主机本地主机 UH 1 180323 lo0 169.254 链接#5 UCS 1 0 en1 cronos.local 链接#5 UHLW 0 1 en1 172.16.20.1 34.108.131.216.cli UH 9 0 ppp0 192.168.1 链接#5 UCS 5 0 en1 192.168.1.1 90:84:d:d3:e2:54 UHLWI 3 1346 en1 1104 192.168.1.98 0:11:24:a2:41:6d UHLWI 2 378 en1 1093 192.168.1.152 0:21:e9:76:fe:6b UHLWI 0 0 en1 637 192.168.1.153 本地主机 UHS 0 118 lo0 192.168.1.154 0:21:5c:52:e0:11 UHLWI 1 2665 en1 1114 192.168.1.255 ff:ff:ff:ff:ff:ff UHLWbI 0 2 en1 strong-sf1.reliabl 192.168.1.1 UGHS 25 25 en1 216.131.108 ppp0 USc 0 0 ppp0
互联网6: 目标网关标志 Netif 过期 本地主机 本地主机 UH lo0 fe80::%lo0 本地主机 Uc lo0 本地主机链接#1 UHL lo0 fe80::%en1 链接#5 UC en1 samuelmacbook.loca 0:1e:c2:a6:64:98 UHL lo0 cronos.local 0:21:5c:52:e0:11 UHLW en1 ff01:: 本地主机嗯 lo0 ff02:: 本地主机 UmC lo0 ff02:: 链接#5 UmC en1
这是我的代码分成 2 个函数
(int)startService { 广播 = 1;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 错误(“套接字”); 退出(1); }
// 这个调用是允许发送广播包的: if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof 广播) == -1) { perror("setsockopt (SO_BROADCAST)"); 退出(1); }
their_addr.sin_family = AF_INET; // 主机字节顺序
their_addr.sin_port = htons(SERVERPORT); // 简短,网络字节顺序
their_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);
返回 0; }
(void)发布服务循环 { NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePool alloc] init]; NSString * 消息;
当(活着){ while ((message = [AdyNetServer encodeToXML:server]) == nil) { [NSThread sleepForTimeInterval:3.0]; } const char * msgString = [消息 cStringUsingEncoding:NSUTF8StringEncoding]; if ((numbytes=sendto(sockfd, msgString, [消息长度], 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) { perror("发送到"); if ([[AdyErrorAlerter sharedInstance] 委托]) { [[[AdyErrorAlerter sharedInstance] 委托] receiveErrorMessage:[NSString stringWithFormat: @"无法广播到套接字 %d,消息为 %@",sockfd,msgString]]; }
}
else {
NSLog(@"wrote %d bytes to socked %d",numbytes,sockfd);
}
//printf("sent %d bytes to %s\n", numbytes,
// inet_ntoa(their_addr.sin_addr));
[NSThread sleepForTimeInterval:1.0];
[autoreleasePool release];
autoreleasePool = [[NSAutoreleasePool alloc] init];
} [自动释放池释放]; 如果(线程!=零){ 线程=零; [线程释放]; } }
【讨论】: