Я не знаю, что вы хотите достичь в конце концов, но работать с UDP не так просто ... основная причина заключается в Описании DatagramPacket объекта:
Датаграмные пакеты используются для реализовать доставка без установления соединения сервис. Каждое сообщение направляется от к одной машине к другой, основанной исключительно на , на информации, содержащейся в этом пакете . Несколько пакетов, отправленных с , одна машина в другую может быть маршрутизирована по-разному и может прийти в любой номер . Доставка пакетов не гарантирована.
Хороший учебник при работе с УДП является http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
Об блокированию:
получает пакет датаграммы от этого гнезда. Когда этот метод возвращается, буфер DatagramPacket заполняется полученными данными. Пакет дейтаграмм также содержит IP-адрес отправителя, и номер порта на машине отправителя .
Этот метод блокируется до тех пор, пока не будет получена датаграмма . Поле длины пакета пакетного объекта содержит длину принятого сообщения . Если сообщение длиннее длины пакета , сообщение усекается.
я действительно не проверить это, но я уверен, - на основе описания - что datagramsocket.reseive функция блокируется, пока пакет не будет заполнен (в вашем случае до 100000 байт не принимаются).
Я предлагаю вам начать с datagrampacket с фиксированной известной длиной, где вы передаете размер фактической полезной нагрузки.Что-то вроде:
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();
}
}
С другой стороны, теперь вы знаете, ваши размеры:
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();
}
}
CientModel CLAS Ši используется:
public class ClientModel implements Serializable{
private static final long serialVersionUID = -4507489610617393544L;
String name = "";
int data = 1;
void print() {
System.out.println(data +": " + name);
}
}
Я тестировал этот код и он работает просто отлично. Надеюсь, что это поможет (я получил byte-To-int и около от http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html)
Редактировать: Как указано в комментариях, часто очень плохо использовать UDP, главным образом потому, что вы не знаете, были ли ваши пакеты принимаются в правильном порядке или даже вообще. UDP НЕ гарантирует это. Я не делал слишком много udp-программирования, но единственной частью, на которую вы можете положиться (если я правильно понял), является то, что если вы получите пакет и он вписывается в дейтаграмму (65,527 байт - см. https://en.wikipedia.org/wiki/User_Datagram_Protocol), он будет содержать все вещь. Поэтому, если вам не нужен порядок, в котором приходит сообщение, и ваш объект вставляется в дейтаграмму, вы должны быть в порядке.
Edit2: Что касается кода: не используйте его как есть. это всего лишь пример, ind UDP, у вас должен быть только один тип пакета, и это с известным размером. таким образом вам не нужно отправлять «размер». Если вы используете код, как показано выше, и один пакет удален, следующий пакет будет неправильного размера (т. Е. Первый пакет будет удален, внезапно вы будете проверять первые байты полезной нагрузки, чтобы получить размер).
Возможно, вам нужно сбросить буфер ... – ultrajohn