-3

私は C++ クライアントを Java バージョンに変更しています - 私が何よりも試している演習です。

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

ありがとう

マーク

試行 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:

        //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);
    }
4

3 に答える 3

2

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

TCP を使用すると、Java レベルでパケットが黙って「ドロップ」されることはありません。これは、OS レベルまたはそれ以下で発生するものです。Java ランタイムに問題があると、例外が発生します。

于 2011-06-28T22:28:11.477 に答える
0

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

于 2011-06-29T03:15:13.300 に答える
0

I've tried your code - much reduced the fp! Still the same result. I've tried with both readInt() and just reading 257 bytes (total inc DWORD) Looking at the data it's almost always missing 30/31 packets of data - suspisious!!. Code below:

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

Example Data (It is binary, the third column is the packet seq id - can't show all of it as some is non printing char's thus shown here is only a part of the data. But I am seeing the whole lot come through when it reads a packet)

ÿþÿ,253, 31, 26,129,105, 94, 65, 67, 31, 23, 2, 9,791, 56, 12, 88, 64, 2,

32-61 missing/not read in

ÿþÿ,253, 62, 26,129,105, 94, 65, 67, 31, 23, 2, 9, 5, 57, 11, 88, 64, 2,

63-91 missing/not read in

ÿþÿ,253, 92, 26,129,105, 94, 65, 67, 31, 23, 2, 9, 5, 57, 12, 88, 64, 2,

于 2011-06-29T10:23:00.690 に答える