如果在 VPN 上广播,C sendto 返回 -1

发布于 2024-09-07 08:54:29 字数 169 浏览 10 评论 0原文

我建立了一个 udp 服务器,它经常广播一条消息。广播没有问题。但是,如果我打开 VPN,那么即使我正在发送到 INADDR_BROADCAST,sendto 也会开始返回 -1。

顺便说一句,如果这改变了什么,我正在 mac 上运行这个。我真的不知道为什么会发生这种情况,我真的想知道udp广播怎么会失败?

I have built a udp server that broadcasts a message every so often. It broadcasts without a problem. But if I turn on my vpn, then sendto will start returning -1 even though I am sending to INADDR_BROADCAST.

I am running this on a mac btw if that changes anything. I really have no idea why this would happen, I am really wondering how could a udp broadcast fail?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囍笑 2024-09-14 08:54:29

您应该检查 errno 全局变量以获取更详细的错误描述。 sendto(2) 手册页。

例如:

[EACCES] 套接字上未设置 SO_BROADCAST 选项,并且给出了广播地址作为目标。

[EHOSTUNREACH]目标地址指定了无法访问的主机。

[ENETUNREACH] 不存在到网络的路由。

You should check errno global variable for more detailed error description. Possible values for this call described at ERRORS section of sendto(2) manual page.

For example:

[EACCES] The SO_BROADCAST option is not set on the socket and a broadcast address is given as the destination.

[EHOSTUNREACH] The destination address specifies an unreachable host.

[ENETUNREACH] No route to the network is present.

∞觅青森が 2024-09-14 08:54:29

我的 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] 向 socked 6 写入 187 个字节
2010-06-25 04:05:57.024 SwypeSendForMac2[63687:6203] 向 socked 6 写入 187 个字节
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:~塞缪尔w$ netstat -r
互联网路由表


目标网关标志参考使用 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 link#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 过期
本地主机 本地主机 呃 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:: link#5 UmC en1

和我的 VPN

34:~ samuelw$ netstat -r
互联网路由表


目标网关标志参考使用 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 link#5 UHLW 0 1 en1
172.16.20.1 34.108.131.216.cli 呃 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
强-sf1.reliabl 192.168.1.1 UGHS 25 25 en1
216.131.108 ppp0 USc 0 0 ppp0

互联网6:
目标网关标记 Netif 过期
本地主机 本地主机 呃 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:: link#5 UmC en1

这是我的代码,分为 2 个函数

  • (int)startService
    {
    广播=1;

    if ((sockfd = 套接字(AF_INET, SOCK_DGRAM, 0)) == -1) {
    错误(“套接字”);
    退出(1);
    }

    // 此调用允许发送广播数据包:
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &广播,
    广播大小) == -1) {
    perror("setsockopt(SO_BROADCAST)");
    退出(1);
    }

    他们的地址.sin_family = AF_INET; // 主机字节顺序

    他们的地址.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)publishServiceLoop
    {
    NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePool alloc] init];
    NSString * 消息;

    当(活着){
    while ((消息 = [AdyNetServerencodeToXML: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) {
    错误(“发送到”);
    if ([[AdyErrorAlerter共享实例]委托]) {
    [[[AdyErrorAlerter共享实例]委托] receiveErrorMessage:[NSString stringWithFormat:
    @“无法广播到套接字%d,消息为%@”,sockfd,msgString]];
    }

    <前><代码> }
    别的 {
    NSLog(@"向 socked %d 写入了 %d 个字节",numbytes,sockfd);
    }

    //printf("已发送 %d 个字节到 %s\n", numbytes,
    // inet_ntoa(ir_addr.sin_addr));
    [NSThread sleepForTimeInterval:1.0];
    [autoreleasePool释放];
    autoreleasePool = [[NSAutoreleasePool alloc] init];

    }
    [autoreleasePool释放];
    if (线程!= nil) {
    线程=零;
    [线程释放];
    }
    }

my errno is 227 (I think) which reads

sendto: Can't assign requested address

I think it can't find a broadcasting port when my vpn gets turned on, here is an example when I turn on my vpn and turn it back off

2010-06-25 04:05:55.022 SwypeSendForMac2[63687:6203] wrote 187 bytes to socked 6
2010-06-25 04:05:56.023 SwypeSendForMac2[63687:6203] wrote 187 bytes to socked 6
2010-06-25 04:05:57.024 SwypeSendForMac2[63687:6203] wrote 187 bytes to socked 6
sendto: Can't assign requested address
sendto: Can't assign requested address
sendto: Can't assign requested address
sendto: Can't assign requested address
sendto: Can't assign requested address
sendto: Can't assign requested address
sendto: Can't assign requested address
2010-06-25 04:06:05.027 SwypeSendForMac2[63687:6203] wrote 187 bytes to socked 6
2010-06-25 04:06:06.031 SwypeSendForMac2[63687:6203] wrote 187 bytes to socked 6

the middle of course is with the vpn on

here is my roouting table without the vpn:

34:~ samuelw$ netstat -r
Routing tables

Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.1.1 UGSc 63 0 en1
127 localhost UCS 0 0 lo0
localhost localhost UH 1 180317 lo0
169.254 link#5 UCS 1 0 en1
cronos.local link#5 UHLW 0 1 en1
192.168.1 link#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 localhost UHS 0 118 lo0
192.168.1.154 0:21:5c:52:e0:11 UHLWI 1 2662 en1 1134

Internet6:
Destination Gateway Flags Netif Expire
localhost localhost UH lo0
fe80::%lo0 localhost Uc lo0
localhost link#1 UHL lo0
fe80::%en1 link#5 UC en1
samuelmacbook.loca 0:1e:c2:a6:64:98 UHL lo0
cronos.local 0:21:5c:52:e0:11 UHLW en1
ff01:: localhost Um lo0
ff02:: localhost UmC lo0
ff02:: link#5 UmC en1

and with my vpn

34:~ samuelw$ netstat -r
Routing tables

Internet:
Destination Gateway Flags Refs Use Netif Expire
default 172.16.20.1 UGSc 8 0 ppp0
default 192.168.1.1 UGScI 1 0 en1
127 localhost UCS 0 0 lo0
localhost localhost UH 1 180323 lo0
169.254 link#5 UCS 1 0 en1
cronos.local link#5 UHLW 0 1 en1
172.16.20.1 34.108.131.216.cli UH 9 0 ppp0
192.168.1 link#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 localhost 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

Internet6:
Destination Gateway Flags Netif Expire
localhost localhost UH lo0
fe80::%lo0 localhost Uc lo0
localhost link#1 UHL lo0
fe80::%en1 link#5 UC en1
samuelmacbook.loca 0:1e:c2:a6:64:98 UHL lo0
cronos.local 0:21:5c:52:e0:11 UHLW en1
ff01:: localhost Um lo0
ff02:: localhost UmC lo0
ff02:: link#5 UmC en1

and here is my code split into 2 functions

  • (int)startService
    {
    broadcast = 1;

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("socket");
    exit(1);
    }

    // this call is what allows broadcast packets to be sent:
    if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
    sizeof broadcast) == -1) {
    perror("setsockopt (SO_BROADCAST)");
    exit(1);
    }

    their_addr.sin_family = AF_INET; // host byte order

    their_addr.sin_port = htons(SERVERPORT); // short, network byte order

    their_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);

    memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);

    return 0;
    }

  • (void)publishServiceLoop
    {
    NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePool alloc] init];
    NSString * message;

    while (alive) {
    while ((message = [AdyNetServer encodeToXML:server]) == nil) {
    [NSThread sleepForTimeInterval:3.0];
    }
    const char * msgString = [message cStringUsingEncoding:NSUTF8StringEncoding];
    if ((numbytes=sendto(sockfd, msgString, [message length], 0,
    (struct sockaddr *)&their_addr, sizeof their_addr)) == -1) {
    perror("sendto");
    if ([[AdyErrorAlerter sharedInstance] delegate]) {
    [[[AdyErrorAlerter sharedInstance] delegate] receiveErrorMessage:[NSString stringWithFormat:
    @"unable to broadcast to socket %d, with message %@",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];
    

    }
    [autoreleasePool release];
    if (thread != nil) {
    thread = nil;
    [thread release];
    }
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文