当 UDP 数据包的接收方尝试读取它时,我收到 EOFException。负责读取和解码 UDP 数据包的实例称为 Engager 对象。它们包含一个在 Engager 的构造函数中创建的套接字,以及一个名为 getEngagementPacketSize 的方法,该方法是接收和读取数据包的地方。这两种方法在这里一起引用:
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;
}
我问这个问题是因为当我尝试读取两个 UDP 数据包中的第一个数据包时,我在接收器上收到 EOFException。因此,我的显示第二个数据包如何打包和发送的代码没有公开(它实际上被注释掉了,所以没有理由怀疑第二个数据包首先被接收)。第一个数据包仅包含一个整数,表示第二个数据包中的字节数。第二个数据包(如果已发送)包含一个参与实例。我没有在这里引用 Engagement 类,因为它的长度(而不是它的形式)很重要。发送方通知我第一个数据包的长度应为 10 个字节;这就是在发送数据包之前执行上面列表中的 System.println 语句时在系统输出窗口中观察到的内容。
为什么接收方无法从数据包中读取整数?问题出在发送方还是接收方?两者皆可吗?
收到的帮助很大。谢谢,
欧文。
最佳答案
Is the problem in the sender or the receiver? Could it be both?
问题出在接收端。您正在像这样分配数据包缓冲区:
byte[] bytes = new byte[Integer.BYTES];
这太小了。如果你看Object Serialization Specification ,您将看到序列化流以 2 字节“魔数(Magic Number)”和 2 字节协议(protocol)版本号开头。因此根据我的计算,缓冲区至少需要 8 个字节……甚至可能更多。
关于java - EOFExceptionon 读取 UDP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36806724/