2016-04-23 12 views
0

UDPパケットの受信者がそれを読み込もうとしたときにEOFExceptionを受け取りました。 UDPパケットの読み取りと復号を担当するインスタンスはEngagerオブジェクトと呼ばれます。それらはEngagerのコンストラクタで作成されたソケットを含み、getEngagementPacketSizeというメソッドはパケットが受信されて読み込まれる場所です。どちらのメソッドもここで引用しています。EOFExcepton reading UDP

例外は、ois.readInt()の呼び出しで発生します。 Senderで

は、パケットが作成したので、送信されます。

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

私は2つのUDPパケットの最初のを読んしようとしたとき、私は受信機でてEOFExceptionを受けるので、私はこの質問をしています。したがって、2番目のパケットがどのようにパッケージ化されて送信されたかを示すコードは公開されていません(実際にはコメントアウトされているので、2番目のパケットが最初に受信されていると思われる理由はありません)。最初のパケットには、2番目のパケットのバイト数を表す整数だけが含まれています。 2番目のパケット(送信された場合)には、エンゲージメントの1つのインスタンスが含まれます。私はここでエンゲージメントクラスを引用していませんが、それは長さ(フォームではない)の問題です。送信者は、最初のパケットは10バイトの長さでなければならないことを通知します。これは、System.printlnステートメントが、パケットが送信される直前の上記の一覧で実行されたときに、システム出力ウィンドウに表示されるものです。

受信者がパケットから整数を読み取ることができないのはなぜですか?送信者または受信者に問題がありますか?両方のことができますか?

大歓迎です。ありがとう、

オーウェン。

答えて

1

送信者または受信者に問題がありますか?両方のことができますか?

問題が受信側にあります。次のようにパケットバッファを割り当てています。

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

これは小さすぎます。 Object Serialization Specificationを見ると、シリアル化ストリームは2バイトの「マジックナンバー」と2バイトのプロトコルバージョン番号で始まることがわかります。だから私の計算では、バッファーは少なくとも8バイトである必要があります...そしておそらくもっと。

+0

Hmmm ...おそらくもっと...ヘッダーパケット(続くパケットの長さを含むもの)の長さが10バイトであることが送信者によってわかっている理由を説明するかもしれません。ヒントをありがとう、私はそれを見て、戻ってきます。 –

+0

@OwenThomas考えられる最小のサイズではなく、予想される最大サイズのデータ​​グラムを使用する必要があります。予想される最大サイズ+ 1、実際には、プロトコルエラーを検出できます。私は1500バイトの領域に何かを提案します。 – EJP

+0

@EJPチップをありがとう。私がしようとしていることは、送信者が光源であり、レシーバのクラスタが網膜であることに最もよく似せることができます。私はUDPが本質的に信頼できないことを知っています。しかし、一度に非常に多数のデバイスにマルチキャストすることになるので、私はいくつかの人がメッセージを受け取り、送信者と正しく対話することを想定しています。それを扱うことができるメッセージを受信しないレシーバーは単にそれを無視します。 –