2012-11-26 33 views
9

PlayCap(http://www.signal11.us/oss/playcap/)によってネットワークアドレス192.168.103.255ポート3000にブロードキャストされるUDPデータを受信しようとしています。私はこのアドレスとポートにバインドする際に問題があります。ここに私のJavaコードは次のとおりです。UDPデータを受信する特定のIPアドレスとポートにバインドする

public static void main(String[] args) { 
    try { 
     DatagramSocket s = new DatagramSocket(); 
     InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000); 
     s.bind(address); 

     byte buffer[] = new byte[1024]; 
     DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 

     System.out.println("Waiting..."); 
     s.receive(packet); 
     System.out.println("Received!"); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

これはエラーを返します:

java.net.SocketException: already bound 
    at java.net.DatagramSocket.bind(Unknown Source) 
    at runner.main(runner.java:12) 

私は "netstatの-a -n" コマンドを実行している、とどちらもアドレス192.168.103.255もポート3000はどこにでもで記載されています出力、私はこのポートが既に使用されているとは思わないので。実際、私は(私の静的IPアドレスを含めて)私が試したどんなアドレス/ポートの組み合わせに対してもこのエラーが出ます。

私はソケットを作成してこのアドレスとポートにバインドするためのCコードも書きましたが、バインドコールでも失敗します。ただし、このコードは静的IPアドレス(192.168.1.149)のポートにバインドされます。そのコードは次のとおりです。

#include <stdio.h> 
#include <sys/types.h> 
#include <winsock.h> 
#include <unistd.h> 

#define a1 192 
#define a2 168 
#define a3 103 
#define a4 255 
#define PORT 3000 

int main() { 

    /* Open windows connection */ 
    WSADATA w; 
    if (WSAStartup(0x0101, &w) != 0) 
    { 
     printf("Could not open Windows connection.\n"); 
     exit(0); 
    } 

    /* Clear out server struct */ 
    SOCKADDR_IN server; 
    memset((void *)&server, '\0', sizeof(struct sockaddr_in)); 

    /* Set family and port */ 
    server.sin_family = AF_INET; 
    server.sin_port = htons(PORT); 
    server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1; 
    server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2; 
    server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3; 
    server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4; 

    /* Open a datagram socket */ 
    int sd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sd == INVALID_SOCKET) 
    { 
     printf("Could not create socket.\n"); 
     WSACleanup(); 
     exit(0); 
    } 

    /* Bind address to socket */ 
    if (bind(sd, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)) == -1) 
    { 
     printf("Could not bind name to socket.\n"); 
     closesocket(sd); 
     WSACleanup(); 
     exit(0); 
    } 

    /* Receive */ 
    char data[1024]; 
    printf("Waiting to receive...\n"); 
    if (recv(sd, (char *)&data, (int)sizeof(data), 0)) 
    { 
     printf("Error receiving data.\n"); 
     closesocket(sd); 
     WSACleanup(); 
     exit(0); 
    } 

    printf("Data: %s", data); 

    return 0; 
} 

私はWindows 7マシンを使用しています。 EclipseでJavaコードを実行しています。私はコマンドを使用してMinGWでCコードをコンパイルしています:

gcc a.c -lws2_32 

( "a.c"はファイル名です)。

Javaコードはより重要ですが、どちらのコード例でもどこが間違っているのか分かりましたら幸いです。どんな提案も非常に感謝しています。

+0

Win32エラーとは何ですか?なぜ静的IPですか? –

+0

なぜあなたは "放送"と静的IPを言っているのですか? –

答えて

12

代わりにJavaコードのためにこれを試してみてください:

public static void main(String[] args) { 
    try { 
     DatagramSocket s = new DatagramSocket(null); 
     InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000); 
     s.bind(address); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

それがランダムに、使用可能なポートにバインドしますデータグラムソケットのための引数なしのコンストラクタを呼び出します。一度バインドされると、(再)バインドを試みると、(あなたが見ているエラーで)ソケット例外がスローされます。バインディングを「延期」するには、コンストラクタでnullを渡してバインドされていない状態でデータグラムソケットを作成し、後でbindを呼び出します。

+0

このエラーを取得するjava.net.BindException:要求されたアドレスを割り当てることができません: \tをjava.net.DualStackPlainDatagramSocketImplにバインドできません。socketBind(ネイティブメソッド)java.net.DualStackPlainDatagramSocketImpl.bind0(不明なソース)java.net.AbstractPlainDatagramSocketImpl.bindで \t(不明なソース)java.net.DatagramSocket.bindで \t(不明なソース)で \t \tでrunner.main(runner.java:11)​​ – ajlitzau13

+0

@ ajlitzau13:私の答えは*なぜ*であるかを説明しています。 –

+0

デフォルトのインターフェイスにバインドして、IPv6の問題を解決してください(インターネットアドレスを削除してポートを使用する)。 – Perception

4

ブロードキャストパケットを受信するブロードキャストアドレスにバインドしません。ポートとアドレスINADDR_ANY(申し訳ありませんが、Javaで表現する方法がわかりません)にバインドするだけで、ブロードキャストアドレスでそのポートにパケットを取得します。

+0

ここはどこですか? 1に近い... –

+0

@KirillKobelev:私は "ポート/アドレスで聴く"は特定のアドレスへのバインディングとして理解されると思うが、私はその言葉を明確にした。 –

+0

これでいいですね。 –

0

appears that Datagramコンストラクタは、バインドするポート番号を受け取ります。希望を助けた...

関連する問題