0

TCP Client で問題が発生しています。サービスはサーバーに接続し、メッセージをリッスンします。メッセージは 90% の確率で受信および処理されます。少しデバッグした後、「データのパケット全体を読み取れません!」というメッセージが表示されることがあることがわかりました。error.(コード内)

サーバーが送信するものを制御できません。私の考えでは、完全なメッセージを受信して​​いません (長いメッセージでは失敗すると思いますが、量が多いため不明です)。

これを説明できる最善の方法は何ですか?、またはその他のヒント。以下に受信メソッドを示します。ここに、すべてのアクションと問題があります。

申し訳ありませんが、TCP を使用するのはこれが初めての試みなので、恐れることはありません

    public void Receive(IAsyncResult ar)
        {
            if (ar != null)
            {
                try
                {

                    byte[] mLenBytes = (byte[])ar.AsyncState;
                    byte[] mDataBytes = null;
                    int bytes_read = mTcpClient.Client.EndReceive(ar);
                    if (bytes_read != 4)
                        throw new Exception("Unable to read whole header!");
                    int len = mLenBytes[3] + ((mLenBytes[2] + (mLenBytes[1] + (mLenBytes[0] << 8)) << 8) << 8);
                    mDataBytes = new byte[len];
                    bytes_read = mTcpClient.Client.Receive(mDataBytes, len, SocketFlags.None);
                    if (bytes_read != len)
                        throw new Exception("Unable to read whole packet of data!" + "Expected " + len + " Got "  + Convert.ToString(bytes_read) + "\r\n" + (System.Text.Encoding.ASCII.GetString(mDataBytes)));
                        //This is the error that is raised!. 

                    // raise an event
                    PhoneBoxEventArgs e1 = new PhoneBoxEventArgs(System.Text.Encoding.UTF8.GetString(mDataBytes));
                    Console.WriteLine("Data received is = " + e1.Data);
                    OnPassEvent(e1);

                }
                catch (Exception ex)
                {

                }

            }
            byte[] mLenBytes_new = new byte[4];
            mTcpClient.Client.BeginReceive(mLenBytes_new, 0, 4, SocketFlags.None, new AsyncCallback(Receive), mLenBytes_new);
        }
4

1 に答える 1

3

TCP サーバーから 1 回の読み取りで「メッセージ」全体を取得するとは想定できません。これが通常、ヘッダー全体を行う理由です。

ヘッダーは 4 バイトの長さと想定されており、何バイト続くかを示します。だからあなたがする必要があるのは:

  1. 4 バイトになるまで非同期で読み取ります
  2. ヘッダーで受信するように指示されたバイト数になるまで、非同期で読み取りを続けます

あなたがしていることは次のとおりです。

  1. 一度に 4 バイトを取得すると仮定し、そうでない場合は失敗します (問題: 1 回の受信で 4 バイトを取得すると仮定することはできません)。
  2. できるだけ多くのバイトを受信し、十分なバイトを取得できなかった場合は失敗します (再び問題: 一度にすべてのバイトを確実に受信することはできません)。

また、コードから、非同期で受信を開始したことがわかります。ヘッダーを取得した後、なぜ同期受信に切り替えるのですか?

于 2012-05-08T10:55:16.243 に答える