私はメッセージを頻繁にブロードキャストするudpサーバーを構築しました。問題なく放送します。しかし、VPNをオンにすると、INADDR_BROADCASTに送信している場合でも、sendtoは-1を返し始めます。
それが何かを変えるなら、私はこれをマックで実行しています。なぜこれが発生するのか本当にわかりません。UDPブロードキャストがどのように失敗するのでしょうか。
私の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] 187 バイトを socked 6 sendto: 要求されたアドレスに割り当てられません sendto: 要求されたアドレスに割り当てられません sendto: 要求されたアドレスに割り当てられません sendto: 要求されたアドレスに割り当てられません sendto:要求されたアドレス sendto を割り当てられません: 要求されたアドレス sendto を割り当てられません: 要求されたアドレス 2010-06-25 04:06:05.027 を割り当てられません SwypeSendForMac2[63687:6203] 187 バイトを socked 6 2010-06-25 04 に書き込みました:06:06.031 SwypeSendForMac2[63687:6203] は socked 6 に 187 バイトを書き込みました
もちろん、真ん中はVPNをオンにした状態です
ここにVPNなしの私のルーティングテーブルがあります:
34:~ samuelw$ netstat -r ルーティング テーブル
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: 宛先ゲートウェイ フラグ 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
そして私のVPNで
34:~ samuelw$ netstat -r ルーティング テーブル
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.9 :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: 宛先ゲートウェイ フラグ 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
ここに私のコードが2つの関数に分割されています
(int) startService { ブロードキャスト = 1;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("ソケット"); 出口 (1); }
// この呼び出しにより、ブロードキャスト パケットの送信が可能になります。出口 (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)publishServiceLoop { NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePool alloc] init]; NSString * メッセージ。
while (alive) { 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("sendto"); if ([[AdyErrorAlerter sharedInstance] delegate]) { [[[AdyErrorAlerter sharedInstance] delegate] 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];
} [autoreleasePool リリース]; if (スレッド != nil) { スレッド = nil; [スレッドリリース]; } }
詳細なエラーの説明については、errno グローバル変数を確認する必要があります。sendto(2)マニュアルページの ERRORSセクションで説明されているこの呼び出しの可能な値。
例えば:
[EACCES] SO_BROADCAST オプションがソケットに設定されておらず、宛先としてブロードキャスト アドレスが指定されています。
[EHOSTUNREACH] 宛先アドレスが到達不能なホストを指定しています。
[ENETUNREACH] ネットワークへのルートが存在しません。