Я получаю исключение EOFException, когда получатель UDP-пакета пытается его прочитать. Экземпляры, которые заряжаются чтением и декодированием UDP-пакетов, называются объектами Engager. Они содержат сокет, который создается в конструкторе Engager, и метод getEngagementPacketSize - это то, где пакет принимается и считывается. Оба метода приведены здесь:EOFExcepton чтение UDP
public Engager(){
MulticastSocket s=null;
try{
s=new MulticastSocket(6789);
s.joinGroup(InetAddress.getByName("224.0.0.1"));
}catch(IOException ex){
ex.printStackTrace(System.out);
}
this.socket=s;
}
private int getEngagementPacketSize()throws Exception{
byte[]bytes=new byte[Integer.BYTES];
DatagramPacket dp=new DatagramPacket(bytes,Integer.BYTES);
this.socket.receive(dp);
ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
ObjectInputStream ois=new ObjectInputStream(bais);
int eps=ois.readInt();
ois.close();
return eps;
}
Исключение происходит при вызове ois.readInt().
На отправителем, пакет создан и отправлен таким образом:
InetAddress ia=null;
try{
ia=InetAddress.getByName("224.0.0.1");
}catch(UnknownHostException ex){
NewInstance_CannotConstructMulticastDestination x=new NewInstance_CannotConstructMulticastDestination(ac);
x.initCause(ex);
throw x;
}
MulticastSocket ms=null;
try{
ms=new MulticastSocket(6789);
ms.joinGroup(ia);
}catch(IOException ex){
NewInstance_CannotConstructMulticastSocket x=new NewInstance_CannotConstructMulticastSocket(ac);
x.initCause(ex);
throw x;
}
NamedSovereignAlias nsa=new NamedSovereignAlias("Self");
Engagement engagement=new Engagement(nsa,nsa,ac.getName(),ac.getPresynapticDelegate());
byte[]engagementBytes=null;
ByteArrayOutputStream baosEngagement=new ByteArrayOutputStream();
try(ObjectOutputStream oos=new ObjectOutputStream(baosEngagement)){
oos.writeObject(engagement);
oos.close();
}catch(Exception ex){
NewInstance_CannotCreateBodyContent x=new NewInstance_CannotCreateBodyContent(ac);
x.initCause(ex);
throw x;
}
engagementBytes=baosEngagement.toByteArray();
byte[]epsBytes=null;
ByteArrayOutputStream baosEps=new ByteArrayOutputStream();
try(ObjectOutputStream oos=new ObjectOutputStream(baosEps)){
oos.writeInt(engagementBytes.length);
oos.close();
}catch(Exception ex){
NewInstance_CannotCreateHeadContent x=new NewInstance_CannotCreateHeadContent(ac);
x.initCause(ex);
throw x;
}
epsBytes=baosEps.toByteArray();
System.out.println("Length of header ["+epsBytes.length+"].");
try{
DatagramPacket dp=new DatagramPacket(epsBytes,epsBytes.length,ia,6789);
ms.send(dp);
}catch(Exception ex){
NewInstance_CannotSendHeadPacket x=new NewInstance_CannotSendHeadPacket(ac);
x.initCause(ex);
throw x;
}
Я задаю этот вопрос, потому что я получаю EOFException на приемнике при попытке прочитать первый из двух UDP пакетов. Следовательно, мой код, показывающий, как упаковывается и отправляется второй пакет, не разглашается (он фактически прокомментирован, поэтому нет оснований подозревать, что второй пакет принимается первым). Первый пакет содержит только целое число, которое представляет количество байтов во втором пакете. Второй пакет (если он был отправлен) содержит один экземпляр взаимодействия. Я не цитировал класс взаимодействия здесь, потому что это длина (а не его форма). Отправитель сообщает мне, что первый пакет должен иметь длину 10 байт; это то, что наблюдается в окне вывода системы, когда оператор System.println выполняется в листинге выше непосредственно перед отправкой пакета.
Почему приемник не может считывать целое число из пакета? Проблема в отправителе или получателе? Может быть, и то, и другое?
Справка очень получена. Спасибо,
Оуэн.
Хммм ... возможно, больше ... это может объяснить, почему отправителю сообщили, что длина пакета заголовка (тот, который содержит длину пакета, который должен следовать) составляет 10 байтов. Спасибо за подсказку, я займусь этим и вернусь. –
@OwenThomas Вам следует использовать дейтаграмму наибольшего ожидаемого размера, а не самое маленькое, о чем вы можете думать. Наибольший ожидаемый размер плюс один, фактически, поэтому вы можете обнаружить ошибки протокола. Я бы предложил что-то в области 1500 байт. – EJP
@EJP Спасибо за подсказку. То, что я пытаюсь сделать, лучше всего сравнить с тем, что отправитель является источником света, а группа приемников - сетчаткой. Я знаю, что UDP по своей сути ненадежен. Однако, поскольку я буду многоадресной рассылкой, возможно, с очень большим количеством устройств одновременно, я предполагаю, что некоторые из них получат сообщение и правильно отправят отправителя. Приемник, который не получает сообщение, с которым он может работать, просто проигнорирует его. –