Ответ 1
Я не знаю, чего вы хотите достичь в конце, но работать с UDP не так просто... Основная причина заключается в описании объекта DatagramPacket:
Пакеты дейтаграмм используются для реализации доставка пакетов без установления соединения оказание услуг. Каждое сообщение направляется из одна машина к другой, основанная исключительно информации, содержащейся в пакет. Несколько пакетов, отправленных с одна машина к другой может быть маршрутизирована по-разному, и может заказ. Доставка пакетов не гарантируется.
Хороший учебник при работе с udp http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
О вашей блокировке:
Получает пакет датаграммы из этого разъем. Когда этот метод вернется, Буфер DatagramPacket заполняется полученные данные. Пакет датаграмм также содержит IP-адрес отправителя, и номер порта на отправителе машина.
Этот метод блокируется до тех пор, пока датаграмма не будет получено. Поле длины пакетный объект датаграммы содержит длина полученного сообщения. Если сообщение больше, чем у пакета длина, сообщение усечено.
Я действительно не тестировал его, но я уверен - на основе описания - что функция datagramsocket.reseive будет блокироваться до тех пор, пока пакет не будет заполнен (в вашем случае до получения 100 000 байтов).
Я предлагаю вам начать с 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 sI используется:
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, у вас должен быть только один тип пакета, и это с известным размером. таким образом вам не нужно отправлять "размер". Если вы используете код, как показано выше, и один пакет отбрасывается, следующий пакет будет неправильным размером (т.е. Первый пакет будет удален, внезапно вы будете проверять первые байты полезной нагрузки, чтобы получить размер).