0

サーバーからクライアントに、基本的に xml オブジェクト (SerializedXMLMessageObject) にシリアル化されたメッセージを送信しています。

逆シリアル化する前に、メッセージ全体を読み取って MemoryStream に蓄積しようとしています。私が抱えている問題は、以下の if-else の「else」部分に入らないことです。読み取りが完了すると、else ステートメントの終了ブラケットにスキップします。

2 つの質問:

  1. ソケットからメッセージ全体を読み取り、サーバーへの接続を維持するにはどうすればよいですか? 以下のコードを修正する簡単な方法はありますか、それとも何らかの区切り記号を提供する必要がありますか?

  2. C# でソケットを介して xml シリアル化されたオブジェクトを送信する例はどこにありますか? 私が遭遇するすべての例は、単純な文字列を送信する方法を示しています。

編集 1: 接続が開いたままになることが期待されます。つまり、クライアントはサーバーに接続されたままになります。

private void callback(IAsyncResult result)
 {
   byte[] data = (byte[])result.AsyncState;

            try
            {
                int read = socket.EndReceive(result);

                if (read > 0)
                {
                    _memoryStream.Write(data, 0, read);
                    socket.BeginReceive(data, 0, 255, SocketFlags.None, new AsyncCallback(callback), data);
                }

                else
                {
                    SerializedXMLMessageObject msg = DeserializeFromXml<SerializedXMLMessageObject >(_memoryStream.ToArray());

                }             

            }
            catch (ObjectDisposedException)
            {
                socket.Close();
            }
        }
4

1 に答える 1

1

アドバイスを受けて、自分の問題に気づきました。

送信側から、送信するメッセージ サイズを計算します。

 byte[] data = ObjectToByteArray(SerializedXMLMessageObject);
 byte[] head = BitConverter.GetBytes(data.Length);
 byte[] total = new byte[data.Length + head.Length];
 head.CopyTo(total, 0);
 data.CopyTo(total, head.Length);

socket.Send(...)

受信側ではそれを StateObject にキャストし、メッセージ サイズを抽出して、完了するまで読み取ります。

stateObject.TotalMessageSize = BitConverter.ToInt32(stateObject.buffer, 0);

……

 if (state.received < state.expected)           
 {
  handler.BeginReceive(state.buffer, 0, StateObject.bufferSize,
                            SocketFlags.None, callback, stateobject);
 }
于 2013-05-10T21:28:36.927 に答える