io non so cosa si vuole realizzare, alla fine, ma lavorare con UDP non è così facile ... la ragione principale è nella descrizione dell'oggetto DatagramPacket:
pacchetti Datagram sono utilizzati per attuare un servizio di consegna senza connessione servizio. Ogni messaggio viene instradato da da un computer all'altro basato esclusivamente su sulle informazioni contenute nel pacchetto . Più pacchetti inviati da un computer a un altro potrebbero essere instradati in modo diverso da e potrebbero arrivare in qualsiasi ordine . La consegna del pacchetto non è garantita .
Un buon tutorial quando si lavora con UDP è http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
Informazioni sul blocco:
riceve un pacchetto datagramma da questa presa . Quando viene restituito questo metodo, il buffer DatagramPacket viene riempito con i dati ricevuti. Il pacchetto datagramma contiene anche l'indirizzo IP del mittente, e il numero di porta sulla macchina del mittente.
Questo metodo blocca fino a quando un datagramma è ricevuto. Il campo lunghezza dell'oggetto pacchetto datagramma contiene la lunghezza del messaggio ricevuto. Se il messaggio è più lungo della lunghezza del pacchetto, il messaggio viene troncato.
Io non ha ancora veramente provarlo, ma sono abbastanza sicuro che - in base alla descrizione - che la funzione datagramsocket.reseive bloccherà fino a quando si riempie il pacchetto (nel tuo caso fino a quando vengono ricevuti 100000 byte).
Suggerirei di iniziare con un datagrampacket con una lunghezza nota fissa, in cui si trasmette la dimensione del carico utile effettivo.Qualcosa di simile:
public static void main(String[] args) {
ClientModel c1 = new ClientModel();
c1.data = 123;
c1.name = "test";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(c1);
oos.flush();
// get the byte array of the object
byte[] Buf= baos.toByteArray();
int number = Buf.length;;
byte[] data = new byte[4];
// int -> byte[]
for (int i = 0; i < 4; ++i) {
int shift = i << 3; // i * 8
data[3-i] = (byte)((number & (0xff << shift)) >>> shift);
}
DatagramSocket socket = new DatagramSocket(1233);
InetAddress client = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(data, 4, client, 1234);
socket.send(packet);
// now send the payload
packet = new DatagramPacket(Buf, Buf.length, client, 1234);
socket.send(packet);
System.out.println("DONE SENDING");
} catch(Exception e) {
e.printStackTrace();
}
}
D'altra parte ora si sa le dimensioni:
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket(1234);
byte[] data = new byte[4];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
int len = 0;
// byte[] -> int
for (int i = 0; i < 4; ++i) {
len |= (data[3-i] & 0xff) << (i << 3);
}
// now we know the length of the payload
byte[] buffer = new byte[len];
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
ByteArrayInputStream baos = new ByteArrayInputStream(buffer);
ObjectInputStream oos = new ObjectInputStream(baos);
ClientModel c1 = (ClientModel)oos.readObject();
c1.print();
} catch(Exception e) {
e.printStackTrace();
}
}
La clas CientModel sI utilizzato:
public class ClientModel implements Serializable{
private static final long serialVersionUID = -4507489610617393544L;
String name = "";
int data = 1;
void print() {
System.out.println(data +": " + name);
}
}
ho provato questo codice e funziona bene. Spero che questo aiuti (ho preso il byte-int e in giro da http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html)
Modifica: come indicato nei commenti, è spesso una pessima idea utilizzare UDP, principalmente, perché non si conoscono i pacchetti sono ricevuti nell'ordine corretto, o addirittura del tutto. UDP NON garantisce questo. Non ho fatto troppa programmazione di udp, ma l'unica parte su cui puoi fare affidamento (se ho capito bene) è che se ottieni un pacchetto e si adatta al datagramma (65.527 byte - vedi https://en.wikipedia.org/wiki/User_Datagram_Protocol) conterrà l'intero cosa. Quindi se non ti interessa l'ordine con cui il messaggio viene e il tuo oggetto si adatta al datagramma, dovresti stare bene.
Edit2: Come per il codice: non usarlo così com'è. è solo un esempio, ind UDP dovresti avere solo un tipo di pacchetto, e questo con una dimensione nota. in questo modo non è necessario inviare la "dimensione". Se si utilizza il codice come mostrato sopra, e un pacchetto viene eliminato, il pacchetto successivo avrà la dimensione sbagliata (ovvero il primo pacchetto viene rilasciato, improvvisamente si stanno verificando i primi byte del payload per ottenere la dimensione).
forse è necessario svuotare il buffer ... – ultrajohn