2012-11-26 6 views
9

Staram się odbierać dane UDP, który jest transmitowany do adresu sieciowego portu 192.168.103.255 3000 przez PlayCap (http://www.signal11.us/oss/playcap/). Mam problemy z powiązaniem z tym adresem i portem. Oto mój kod Java:Oprawa do konkretnego adresu IP i portu do odbioru danych UDP

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(); 
    } 
} 

ta zwraca błąd:

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

mam uruchomić polecenie "netstat -a -n", a nie adres 192.168.103.255 ani portów 3000 są wymienione w dowolnym miejscu wyjście, więc nie sądzę, że ten port jest już w użyciu. W rzeczywistości dostaję ten błąd dla dowolnej kombinacji adresu/portu, którego próbuję (w tym mojego statycznego adresu IP).

ja też trochę kodu C, aby gniazdo i wiążą się z tym adresem i portem, ale też nie na wezwanie bind. Ten kod będzie jednak wiązał się z portami na moim statycznym adresie IP (192.168.1.149). Oto kod:

#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; 
} 

Używam komputera z systemem Windows 7. Używam kodu Java w Eclipse. Kompiluję kod C za pomocą polecenia MinGW za pomocą polecenia:

gcc a.c -lws2_32 

("a.c" to nazwa pliku).

Chociaż kod Java jest ważniejsze, byłbym szczęśliwy, aby wiedzieć, gdzie będę źle w każdym z moich przykłady kodu. Wszelkie sugestie są bardzo doceniane.

+0

Jakie są błędy Win32? Dlaczego statyczne IP? –

+0

dlaczego mówisz "broadcast", a następnie statyczne IP? –

Odpowiedz

12

Spróbuj na kodzie Java Zamiast:

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(); 
    } 
} 

Wywołanie konstruktora nie-Arg na gniazdo datagramu spowoduje to wiązać się losowo, dostępnego portu. Po związaniu dalsze próby ponownego wiązania spowodują zgłoszenie wyjątku gniazda (z powodu błędu, który wystąpił). Aby "odroczyć" wiązanie, należy zamiast tego utworzyć gniazdo datagramowe w stanie niezwiązanym (poprzez podanie wartości null w konstruktorze), a następnie wywołanie bind.

+0

otrzymuję ten błąd: java.net.BindException: nie można przypisać żądany adres: Nie można powiązać \t na java.net.DualStackPlainDatagramSocketImpl.socketBind (Metoda Ojczysty) \t na java.net.DualStackPlainDatagramSocketImpl.bind0 (Unknown Source) \t na java.net.AbstractPlainDatagramSocketImpl.bind (Unknown Source) \t na java.net.DatagramSocket.bind (Unknown Source) \t na runner.main (runner.java:11) – ajlitzau13

+0

@ ajlitzau13: Moja odpowiedź wyjaśnia, * dlaczego * tak jest. –

+0

Spróbuj przywiązać do domyślnego interfejsu, aby wyeliminować problemy z IPv6 (usuń adres internetowy i po prostu użyj portu). – Perception

4

Nie wiążą się adres broadcast do odbierania pakietów rozgłoszeniowych. Wystarczy połączyć się z portem i adresem INADDR_ANY (przepraszam, nie wiem, jak wyrazić to w Javie), a otrzymasz pakiety do tego portu na adres broadcast.

+0

Gdzie jest tutaj? Blisko -1 ... –

+0

@KirillKobelev: Myślę, że "słuchaj na porcie/adresie" jest rozumiany jako wiążący dla konkretnego adresu, ale ja doprecyzowałem jego treść. –

+0

Teraz brzmi lepiej. –

0

To appears that konstruktor Datagram bierze numer portu do wiązania. Nadzieja, która pomogła ...

Powiązane problemy