Visualizzazione dei risultati da 1 a 9 su 9
  1. #1

    [java]DatagramPacket UDP

    Salve a tutti, tengo problemi nella trasmissione di pacchetti UDP, in particolare tengo un server che in seguito ad una richiesta del client, risponde con un messaggio di accettazione così composto:

    CIAO indirizzoip porta

    "CIAO" di 4bytes; "indirizzo ip" di 4bytes; "porta" intero di 2 bytes.
    Non trovo problemi a inviare un messaggio contenente solo una stringa, ad esempio la stringa "CIAO" scrivendo:
    codice:
    byte buf[] = new byte[4]; buf = "CIAO".getBytes();    DatagramPacket pack = new DatagramPacket(buf, buf.length,group, port);  s.send(pack);//dove s è un DatagramSocket
    Il problema nasce quando devo inviare un messaggio tipo quello sopradetto.
    Grazie in anticipo

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [java]DatagramPacket UDP

    Originariamente inviato da Easyrub26
    CIAO indirizzoip porta

    "CIAO" di 4bytes; "indirizzo ip" di 4bytes; "porta" intero di 2 bytes.
    Non trovo problemi a inviare un messaggio contenente solo una stringa, ad esempio la stringa "CIAO" scrivendo:
    codice:
    byte buf[] = new byte[4];
    buf = "CIAO".getBytes();
    DatagramPacket pack = new DatagramPacket(buf, buf.length,group, port);
    s.send(pack);//dove s è un DatagramSocket
    Con questo codice il "pacchetto" contiene solo il "CIAO" ... mi pare ovvio. E tra l'altro istanziare prima l'array di 4 byte così sarebbe superfluo, perché il getBytes fornisce un nuovo array.

    Dovresti comporre tu un buffer che contiene tutto. Ma ci sono delle cose che devi prima stabilire. Parli di valori "interi" a più byte, quindi devi prima decidere se scriverli in Big-Endian o Little-Endian.
    Se ti va bene Big-Endian, usa DataOutputStream+ByteArrayOutputStream. Puoi scrivere dati primitivi e altro tramite DataOutputStream che vanno in ByteArrayOutputStream di cui puoi ottenere il buffer byte[] completo.

    Ma c'è una cosa che mi domando: questo IP e porta che vuoi mettere nel pacchetto .... di chi sono?? Del mittente? Allora non servono. Chi riceve il DatagramPacket non ha problemi a capire da quale IP/porta remota proviene il pacchetto! I metodi ci sono ....
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Innanzitutto grazie per la risposta, ho chiaro fino a un certo punto quello che mi hai detto.I valori interi a più byte vanno scritti in Big-Endian. Ho provato a scrivere il codice usando DataOutputStream+ByteArrayOutputStream in questo modo :
    codice:
    byte[] data = new byte[10];// array di 10 bytes per contenere l intero msg
     DatagramPacket dp = new DatagramPacket(data, data.length, group, port);  
    
    ByteArrayOutputStream bout = new ByteArrayOutputStream(); 
    DataOutputStream dout = new DataOutputStream(bout); 
    dout.writeUTF(hello); // scrivo la stringa "HELO" sullo stream 
    data = bout.toByteArray(); // estraggo l' array di byte 
    dp.setData(data,0,data.length); // lo inserisco nel DatagramPacket 
    dp.setLength(data.length); // definisco la lunghezza del buffer 
    s.send(dp); // invio il DatagramPacket sul socket s dichiarato in precedenza
    Con questo codice invio nuovamente solo una stringa, se volessi inviare anche un indirizzo ip di 4bytes(l indirizzo in questione che mi chiedi è quello del server e anche la porta; entrambi serviranno al client per contattare il server in seguito tramite TCP) come faccio? Ho visto che ci sono metodi come "writeIint" che può andar bene per inviare il numero di porta, ma per l indirizzo ip come mi comporto dato che è un InetAddress?
    Spero di esser stato chiaro, sono un pò alle prime armi. Grazie

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Easyrub26
    Ho visto che ci sono metodi come "writeIint" che può andar bene per inviare il numero di porta
    Appunto.

    Originariamente inviato da Easyrub26
    ma per l indirizzo ip come mi comporto dato che è un InetAddress?
    InetAddress ti permette di ottenere un byte[] con l'indirizzo. Che tra l'altro è in "network order" (che poi vuol dire Big-Endian).


    P.S. Fare:
    byte[] data = new byte[10]; // Non serve istanziare
    ...
    data = bout.toByteArray(); // Qui fornisce già un nuovo array.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    InetAddress ti permette di ottenere un byte[] con l'indirizzo. Che tra l'altro è in "network order" (che poi vuol dire Big-Endian).
    Io l' InetAddress lo ricavo prima con l invocazione del metodo " getByName(String host)" che mi restituisce l' indirizzo ip. Adesso come faccio ad inviare questo dato sullo stream creato? Non riesco a trovare tra le API il metodo giusto.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Easyrub26
    Io l' InetAddress lo ricavo prima con l invocazione del metodo " getByName(String host)" che mi restituisce l' indirizzo ip. Adesso come faccio ad inviare questo dato sullo stream creato? Non riesco a trovare tra le API il metodo giusto.
    InetAddress ha un metodo di "istanza" che restituisce un byte[].
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Originariamente inviato da andbin
    InetAddress ha un metodo di "istanza" che restituisce un byte[].
    Parli del metodo "getAddress()"? Se non ti dispiace potresti farmi un esempio?

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Easyrub26
    Parli del metodo "getAddress()"? Se non ti dispiace potresti farmi un esempio?
    Scusa ma quale esempio vuoi??! È un metodo di istanza .... hai ottenuto il InetAddress (dal getByName)? Bene, ci invochi poi getAddress. Non capisco la difficoltà.


    E comunque io, fossi in te, mi preoccuperei di valutare anche altre cose. Non so cosa devi fare di preciso, quale è il "server" (tuo, sviluppato da te?) o altro.

    Ma se fai:

    dout.writeUTF(hello); // scrivo la stringa "HELO" sullo stream

    Non scrive solo 4 byte per "HELO" ma ne scrive 6. writeUTF prevede la scrittura della stringa con un formato particolare (è un UTF-8 modificato per non iniettare byte nulli) dove ci sono 2 byte per la lunghezza che precedono lo stream della stringa.

    E come seconda cosa: chi riceve che cosa "sa" di questo pacchetto?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Ciao, hai ragione sul metodo "writeUTF", scrive 2 btye in più e nel mio caso non va bene; quindi ho risolto in questo modo :
    codice:
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(baos);
     char[] header = new char[]{'H','E','L','O'}; 
    for(int i = 0;i<4;i++){ dos.write((int)header[i]); } 
    dos.write(ip.getAddress()); 
    dos.write(toByte(port));
    Grazie

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.