2011-06-28 15 views
-3

C++クライアントをJavaバージョンに変更しています。これは何よりも挑戦しています。Javaクライアントを使用してTCPを読み取るときにパケットが欠落/欠落する

元のC++コードは完全にうまく機能します。 Servce側がDWORDを送信すると、クライアントはこれを探して、次に253バイトのデータを読み取ります。私はJavaで多くの成功を収めてこれを試してきました。以下は私が試した異なるコードブロックのカップルです。誰かが私が間違っているとき私に言うことができるなら、私はそれを最も感謝しています。

おかげ

マーク

試み1:

 //Create socket connection 
    try 
    { 
     client = new Socket("localhost", 7651); 
     //in = client.getInputStream(); 
     reader = new BufferedReader(new 
       InputStreamReader(client.getInputStream(), "ISO-8859-1")); 
    } 
    catch (UnknownHostException e) 
    { 
     System.out.println("Unknown host: localhost"); 
     System.exit(1); 
    } 
    catch (IOException e) 
    { 
     System.out.println("No I/O"); 
     System.exit(1); 
    } 

    //Receive data from ROS SerialtoNetwork server 

    while (true) 
    { 
     // Read repeatedly until the expected number of chars has been read: 
     char[] buf = new char[300]; 
     int numberRead = 0; 

     int numberToRead = 257; 
     for (int totalCharsRead = 0; totalCharsRead < numberToRead;) 
     { 
      int numberLeft = numberToRead - totalCharsRead; 

      try { 
       numberRead = reader.read(buf, totalCharsRead, numberLeft); 

       if (numberRead < 0) 
       { 
        // premature end of data 
        break; 
       } 
       else 
       { 
        totalCharsRead += numberRead; 
       }    
      } 
      catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     String lstr = new String(buf); 
     System.out.print(lstr); 

     System.out.println(""); 
     System.out.println("Bytes Received:" + numberRead); 
    } 

が試み2: "試行1" では

 //Create socket connection 
    try 
    { 
     client = new Socket("localhost", 7651); 
     in = client.getInputStream();   
    } 
    catch (UnknownHostException e) 
    { 
     System.out.println("Unknown host: localhost"); 
     System.exit(1); 
    } 
    catch (IOException e) 
    { 
     System.out.println("No I/O"); 
     System.exit(1); 
    } 

    //Receive data from ROS SerialtoNetwork server 

    try 
    { 
     while (true) 
     { 
      byte[] cbuf = new byte[300]; 
      int lBytesAvail = in.available();//read(cbuf, 0, 4); 

      if (lBytesAvail > 253) 
      { 
       in.read(cbuf, 0, 4); 
       int lBytesRead = in.read(cbuf, 0, 253); 

       String lstr = new String(cbuf); 
       System.out.print(lstr); 

       System.out.println(""); 
       System.out.println("Bytes Received:" + lBytesRead); 
      } 

     } 
    } 
    catch (IOException e) 
    { 
     System.out.println("Read failed"); 
     System.exit(1); 
    } 
+1

**クライアントはパケット**をたくさんドロップしていますか?ネットワークトラフィックを監視していて、実際のパケットがドロップされていますか?それとも、20バイトのうち1バイトしか読み込まれないということですか? 2つの問題は完全に分離されており、前者はおそらくハードウェアに関連している(または接続に関連している)おそらく後者はおそらくコード内のバグです。 – SRM

答えて

0

私はあなたのコードを試しました - はるかにfpを減らしました!それでも同じ結果。私は両方のreadInt()とちょうど257バイト(合計inc DWORD)を読んでみました。データを見ると、ほとんどの場合、データの30/31パケットが欠落しています。以下のコード:

  try 
    { 
     lSocket = new Socket("localhost", 7651); 
     lDataStream = new DataInputStream(lSocket.getInputStream()); 

    } 
    catch (UnknownHostException e) 
    { 
     System.out.println("Unknown host: localhost"); 
     System.exit(1); 
    } 
    catch (IOException e) 
    { 
     System.out.println("No I/O"); 
     System.exit(1); 
    } 

    //Receive data from ROS SerialtoNetwork server 

    try 
    { 
     while(true) 
     { 
      //in.readInt(); 
      byte[] cbuf = new byte[257]; 
      lDataStream.readFully(cbuf);   

      String lstr = new String(cbuf); 
      System.out.print(lstr); 

      System.out.println(""); 
     }    
    } 
    catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

例データ(これはバイナリであり、第3列は、パケット配列番号である - いくつかは、非印刷文字のので、ここで示されているように、それのすべてを表示することができないデータの一部のみです。しかし、私はパケットが読み込まれるときに全体のロットが来るのを見ている)

¡±,253,31,26,129,105,94,65,67,31,23,2,9,791,56,12,88,64,2 、欠落

32から61/

ÿþÿ、253、62、26129105、94、65、67、31、23、2、9、5、57、11、88、64に読んでいません、 2、

63から91は

ÿþÿ、253、92、26129105、94、65、67、31、23、2、9、5、57、12、88、64、で読み出し/ていない欠落します2、

+0

大丈夫です。上のすべてのコードオプション(Phew!)はプロトコルエラーでした。 Doh !.しかし、アドバイスをありがとう。 – Mark

2

、あなたはnumberRead、ないtotalCharsReadを印刷しています。 numberReadは、バッファ内の合計ではなく、最後の操作で読み取られた数字文字です。ローカル変数のスコープを可能な限り制限し、ダミー値で早期に初期化しないようにすることで、このバグを回避できます。これにより、コードが読みやすくなります。

TCPの場合、パケットはJavaレベルでサイレントに「ドロップ」されません。これは、OSレベル以下で発生するものです。 Javaランタイムに問題があると、例外が発生します。

+0

返事をありがとう。再:データ項目の数を印刷 - いくつかのデバッグ、私の間違い。基本的に、このデータはサーバーからストリームアウトされます。C++クライアントを使用すると、すべてのパケットが正しく受信されます。 Javaのものは約20分の1しか表示されません。 – Mark

+0

@マーク - どちらの場合でも、読み取ったバイト数を決定する方法は明らかではありません。最初はバグがあり、後者ではバグがありません。どちらのバージョンでもサンプル出力を提供しません。 Javaはパケットを破棄しません。バグはあなたのコードにあります。だから、それを理由として却下するのではなく、実際のコードとその結果を掲示してください。 – erickson

0

送信者がバイナリデータを送信している場合は、最初にリーダーで間違ったツリーを樹立しています。 DataInputStream.readInt()を使用してDWORDを読み取り、次にDataInputStream.readFully()を使用してデータを読み取ります。そして、ひどいループ/カウントコードをすべて投げ捨ててください。