EOF异常读取UDP

EOFExcepton reading UDP

当 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 实例。我没有在这里引用 Engagement class 因为它的长度(而不是它的形式)很重要。发件人告诉我第一个数据包的长度应该是 10 个字节;这就是在发送数据包之前在上面的列表中执行 System.println 语句时在系统输出 window 中观察到的结果。

为什么接收方无法从数据包中读取整数?问题出在发送方还是接收方?可以两者兼而有之吗?

大受帮助。谢谢,

欧文.

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 字节协议版本号开头。所以根据我的计算,缓冲区需要至少 8 个字节......可能更多。