2012-11-26 11 views
9

Sto tentando di ricevere dati UDP trasmessi all'indirizzo di rete 192.168.103.255 porta 3000 di PlayCap (http://www.signal11.us/oss/playcap/). Ho problemi con l'associazione a questo indirizzo e porta. Ecco il mio codice Java:Collegamento a uno specifico indirizzo IP e porta per ricevere dati 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(); 
    } 
} 

Questo restituisce l'errore:

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

Ho eseguito il comando "netstat -a -n", e né l'indirizzo né 192.168.103.255 porta 3000 sono elencati in qualsiasi parte l'output, quindi non penso che questa porta sia già in uso. In effetti, ottengo questo errore per qualsiasi combinazione di indirizzo/porta che provo (incluso il mio indirizzo IP statico).

Ho anche scritto un codice C per creare un socket e collegarlo a questo indirizzo e porta, ma non riesce anche alla chiamata di bind. Questo codice, tuttavia, si collegherà alle porte sul mio indirizzo IP statico (192.168.1.149). Ecco il codice:

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

Sto usando una macchina Windows 7. Sto eseguendo il codice Java in Eclipse. Sto compilando il codice C con MinGW utilizzando il comando:

gcc a.c -lws2_32 

("a.c" è il nome del file).

Mentre il codice Java è più importante, sarei felice di sapere dove sto andando male in uno dei miei esempi di codice. Qualsiasi suggerimento è molto apprezzato.

+0

Quali sono gli errori di Win32? Perché l'IP statico? –

+0

perché stai dicendo "broadcast" e quindi IP statico ?? –

risposta

12

Prova questo per il codice Java, invece:

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

Chiamando il costruttore no-arg per un datagram socket causerà di legarsi a una, porta disponibile casuale. Una volta associati, ulteriori tentativi di (re) binding genereranno un'eccezione socket (con l'errore che si stava vedendo). Per il binding "posticipato", si crea invece il socket del datagramma in uno stato non associato (passando un null nel costruttore), quindi chiamando in seguito bind.

+0

Ottenere questo errore: java.net.BindException: impossibile assegnare l'indirizzo richiesto: impossibile associare \t a java.net.DualStackPlainDatagramSocketImpl.socketBind (metodo natale) \t a java.net.DualStackPlainDatagramSocketImpl.bind0 (fonte sconosciuta) \t a java.net.AbstractPlainDatagramSocketImpl.bind (Fonte sconosciuta) \t a java.net.DatagramSocket.bind (Fonte sconosciuta) \t a runner.main (runner.java:11) – ajlitzau13

+0

@ ajlitzau13: La mia risposta spiega * perché * è così. –

+0

Provare a legare all'interfaccia predefinita, per eliminare i problemi IPv6 (rimuovere l'indirizzo Internet e utilizzare solo la porta). – Perception

4

Non si associa l'indirizzo di trasmissione per ricevere i pacchetti di trasmissione. Collega semplicemente la porta e l'indirizzo INADDR_ANY (mi spiace, non sono sicuro di come esprimerlo in Java) e riceverai i pacchetti su quella porta sull'indirizzo di trasmissione.

+0

Dov'è l'ascolto qui ?? Close to -1 ... –

+0

@KirillKobelev: Penso che "ascoltare su una porta/indirizzo" sia da intendersi come vincolante per un particolare indirizzo, ma ho chiarito il testo. –

+0

Ora suona meglio. –

0

E appears that il costruttore Datagramma accetta il numero di porta a cui eseguire il binding. Spero che questo abbia aiutato ...

Problemi correlati