2016-04-23 12 views
0

Ich erhalte eine EOFException, wenn der Empfänger eines UDP-Pakets versucht, es zu lesen. Instanzen, die UDP-Pakete lesen und dekodieren, heißen Engager-Objekte. Sie enthalten einen Socket, der im Konstruktor von Engager erzeugt wird, und eine Methode namens getEngagementPacketSize, in der das Paket empfangen und gelesen wird. Beide Verfahren sind zusammen hier zitiert:EOFExcepton Lesen 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; 
} 

Die Ausnahme tritt auf dem Aufruf von ois.readInt().

Auf dem Sender wird das Paket erstellt und somit gesendet:

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; 
    } 

Ich stelle diese Frage, weil ich einen EOFException auf dem Empfänger, wenn ich versuche, die ersten von zwei UDP-Paketen zu lesen erhalten. Daher wird mein Code, der zeigt, wie das zweite Paket verpackt und gesendet wird, nicht offenbart (es ist tatsächlich auskommentiert, so dass kein Grund besteht, zu vermuten, dass das zweite Paket zuerst empfangen wird). Das erste Paket enthält nur eine ganze Zahl, die die Anzahl der Bytes im zweiten Paket darstellt. Das zweite Paket (falls es gesendet wurde) enthält eine einzelne Instanz eines Auftrags. Ich habe die Engagement-Klasse hier nicht zitiert, da es auf die Länge (nicht auf die Form) ankommt. Der Absender informiert mich, dass das erste Paket 10 Bytes lang sein sollte; Dies wird im Systemausgabefenster beobachtet, wenn die Anweisung System.println in der obigen Liste ausgeführt wird, unmittelbar bevor das Paket gesendet wird.

Warum kann der Empfänger die ganze Zahl nicht aus dem Paket lesen? Liegt das Problem beim Absender oder beim Empfänger? Könnte es beides sein?

Hilfe stark erhalten. Danke,

Owen.

Antwort

1

Ist das Problem im Absender oder im Empfänger? Könnte es beides sein?

Das Problem ist auf der Empfängerseite. Sie ordnen den Paketpuffer wie folgt zu:

byte[] bytes = new byte[Integer.BYTES]; 

Das ist zu klein. Wenn Sie sich die Object Serialization Specification ansehen, werden Sie sehen, dass ein Serialisierungsstrom mit einer 2-Byte- "magischen Zahl" und einer 2-Byte-Protokollversionsnummer beginnt. Also muss der Puffer nach meinen Berechnungen mindestens 8 Bytes haben ... und möglicherweise mehr.

+0

Hmmm ... möglicherweise mehr ... das könnte erklären, warum mir vom Absender gesagt wird, dass die Länge des Header-Pakets (dasjenige, das die Länge des Pakets enthält, das folgen soll) 10 Bytes ist. Danke für den Tipp, ich schaue hinein und komme zurück. –

+0

@OwenThomas Sie sollten ein Datagramm der größten erwarteten Größe verwenden, nicht das kleinste Sie denken können. Größte erwartete Größe plus eins, um Protokollfehler zu erkennen. Ich würde etwas im Bereich von 1500 Bytes vorschlagen. – EJP

+0

@EJP Danke für den Tipp. Was ich zu tun versuche, könnte am besten mit dem Sender verglichen werden, der eine Lichtquelle ist, und der Cluster von Empfängern ist eine Retina. Ich weiß, UDP ist von Natur aus unzuverlässig. Da ich jedoch zu einer sehr großen Anzahl von Geräten gleichzeitig croscaste, stelle ich mir vor, dass einige von ihnen die Nachricht erhalten und den Absender korrekt einbeziehen. Ein Empfänger, der keine Nachricht erhält, mit der er arbeiten kann, ignoriert sie einfach. –