2

まず最初に、私の状況を説明しましょう。私は、通信にソケットを使用するC#のクライアントとサーバーで作業しています。

実用上の理由から、私は両方のソケットの非同期部分を使用して、バイナリシリアル化されたオブジェクトをクライアントからサーバーに、またはその逆に送信します。

私の問題は、一度に送信するオブジェクトが多すぎると、レシーバーオブジェクトがバッファーに「スタック」し、バッファーコンテンツのシリアル化を解除しようとすると、オブジェクトが1つだけになることです。

私の質問は:各オブジェクトをバッファから分離するにはどうすればよいですか?

これが私のReceiveCallback関数です:

private void ReceiveMessageCallback(IAsyncResult asyncResult)
    {
        Socket socket = (Socket)asyncResult.AsyncState;
        try
        {
            int read = socket.EndReceive(asyncResult);
            if (read > 0)
            {
                Log("Reception of " + read + " Bytes");

                // Jumper is an object that I use to transport every message
                Jumper pod = Common.Serializer.DeSerialize<Jumper>(this.readbuf);

                Buffer.SetByte(this.readbuf, 0, 0);
                socket.BeginReceive(this.readbuf, 0, this.readbuf.Length, SocketFlags.None, new AsyncCallback(ReceiveMessageCallback), socket);

                //We fire an event to externalise the analyse process
                Receiver(pod, socket);
            }
        }
        catch (SocketException ex)
        {
            if (ex.SocketErrorCode == System.Net.Sockets.SocketError.ConnectionReset)
            {
                socket.Close();
                Log("Distant socket closed");
            }
            else
                Log(ex.Message);
        }
        catch (Exception ex)
        {
            Log(ex.Message);
        }
    }
4

1 に答える 1

0

デシリアライズは、1つのオブジェクトのバッファーを消費し、次のオブジェクトの開始時にバッファーの「読み取りポインター」を残します。

私の提案は次のいずれかになります。

  • ソケットストリームから他の(メモリ)バッファにデータを移動し、そこから逆シリアル化し、「バッファリング」全体を手動で制御します

また

  • コールバックを受け取ったら、例外が発生するまで、deserializeを連続して数回呼び出します。

ソケットに接続されているストリームはバイトのシーケンスであり、いつでも壊れることがあるため、2番目のアプローチは失敗する可能性があります。これは、一度にすべてのオブジェクトを取得できることを誰も保証できないためです。

それが理にかなっていることを願っています。

編集:

実際、これを行うための適切な方法は、各「メッセージ」(送信時にシリアル化されたオブジェクト)をパケットにカプセル化することです。たとえば、パケットの長さを示す小さなヘッダーがあり、受信すると、完全なパケットデータが得られるまでソケットストリームを読み取り、シリアル化します。そして、次のパケットなど。

さらに:

送信側で1000バイトのレートでデータをソケットに送信するとします。受信側では、おそらくソケットから1000 x 1000バイトを取得することは決してないでしょう。実際、次の2つの条件下でのみ期待できます。

  • 各送信間の遅延は非常に大きく、送信間の読み取りは受信側で発生します
  • 純粋な事故
于 2012-06-15T15:46:51.087 に答える