【问题标题】:C sendto returns -1 if broadcasting on a vpn如果在 vpn 上广播,C sendto 返回 -1
【发布时间】:2010-06-24 11:56:22
【问题描述】:

我已经建立了一个 udp 服务器,它每隔一段时间就会广播一条消息。它广播没有问题。但是如果我打开我的 vpn,即使我正在发送到 INADDR_BROADCAST,sendto 也会开始返回 -1。

如果这有什么改变,我会在 mac 上运行它。我真的不知道为什么会发生这种情况,我真的很想知道 udp 广播怎么会失败?

【问题讨论】:

    标签: c vpn sendto


    【解决方案1】:

    您应该检查 errno 全局变量以获得更详细的错误描述。在sendto(2) 手册页的错误部分中描述了此调用的可能值。

    例如:

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

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

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

    【讨论】:

      【解决方案2】:

      我的 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];
        

        } [自动释放池释放]; 如果(线程!=零){ 线程=零; [线程释放]; } }

      【讨论】:

        猜你喜欢
        • 2016-09-10
        • 1970-01-01
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        • 2016-01-09
        • 2020-08-18
        • 1970-01-01
        • 2023-03-15
        相关资源
        最近更新 更多