2016-12-06 13 views
0

ローカルネットワーク上のデバイスをスキャンするUDPブロードキャストを送信するコードがあります。私はイーサネット経由でプラグインしてもうまく動作しますが、WiFi経由で接続しているときはうまくいきません。WiFi経由のUDPソケットからの読み取りは常にタイムアウト

のWiFiを使用するときにUDPで接続するために行うには別の何かがありますか?

以下のコードを使用して見つけることができます。でも、無線LANを使用して、私はTCP接続をestalbishし、デバイス、仕事

注2 doesntのそのわずかUDPブロードキャストと通信することができます:現在のテストを無線LANを使用する場合は、selectは常に0

struct sockaddr_in addr; 

//Create socket 
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) 
{ 
    perror("socket"); 
    exit(1); 
} 

/* set up destination address */ 
memset((char *)&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(48620); 
addr.sin_addr.s_addr = inet_addr("192.168.3.255"); 

//TRYING TO BIND, NOT WORKING 
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) 
{ 
    int a = WSAGetLastError(); //ERROR 10049 
    perror("bind"); //Says NO ERROR 
    } 


//allow broadcast 
int broadcast = 1; 
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*)&broadcast, sizeof(broadcast)) == -1) 
    exit(1); 


    if (sendto(fd, (const char *)&request, sizeof(request), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) 
    { 
     perror("sendto"); 
     exit(1); 
    } 

    do 
    { 
     FD_ZERO(&rdFs); 
     FD_SET(fd, &rdFs); 
     lTimeout.tv_sec = 1; 
     lTimeout.tv_usec = 000000; 
     lSelRet = select(fd, (fd_set*)&rdFs, NULL, NULL, &lTimeout); 
     if (lSelRet > 0 && FD_ISSET(fd, &rdFs)) 
     { 
      addrFromSize = sizeof(addrFrom); 
      lResult = recvfrom(fd, bufferIn, sizeof(bufferIn), 0, (struct sockaddr *) &addrFrom, &addrFromSize); 
      //Treat result 
     } 
    } while (lSelRet > 0); 

注意を返します窓、私

編集後のLinuxへの意志ポート、それは最後にそれが働いてしまったレミー

+0

WiFiとEthernetの違いはありません。それらは、同じネットワークへの接続の種類だけです。 OSはあなたのために違いを処理します。つまり、 'select()'に渡す最初のパラメータの値は間違っているので、代わりに 'fd + 1'にする必要があります(Windows上で実行している場合を除き、パラメータは単に無視されます)。また、IPv4ブロードキャストアドレスを使ってパケットを送受信する前に、 'setsockopt()'を使ってソケットの 'SO_BROADCAST'オプションを有効にする必要があります。 –

+0

私はWiFiとイーサネットについて考えたことはありますが、一方は動作していて、もう一方は動作していません。私はSO_BROADCASTを試してみて、投稿しておきます –

+0

@RemyLebeau SO_BROADCASTを追加しました(編集したコードを参照してください)。問題はどこか他の場所だと思います。私がイーサネットを接続してコードを起動してプラグを抜くと、コードはWiFiを使って動作し続けます。 –

答えて

0

の助言としてSO_BROADCASTを追加し、それがコードの問題ではなく、ルータの問題でした。

問題は、私は私のIPはなくブロードキャストIPを使用するために必要なバインド機能の誤用でした。

/* set up destination address */ 
memset((char *)&addr, 0, sizeof(addr)); 
addr.sin_family = AF_INET; 
addr.sin_port = htons(48620); 
addr.sin_addr.s_addr = inet_addr("192.168.3.134"); //<== Windows : My IP, not the broadcast IP 
addr.sin_addr.s_addr = INADDR_ANY; //Linux 

if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) 
{ 
    perror("bind"); 
} 

EDIT:不思議なこと、窓にあなたがリクエストを送信するIPにバインドする必要があります。また、Linux上で、あなたがINADDR_ANYにバインドする必要があります。

関連する問題