-3

重複の可能性:
C#で複雑なオブジェクトを非同期で受信する方法は?

私の複雑なオブジェクトはIOrderedQueryable型です。4つの属性があり、すべてList型です。

これを介して非同期ソケットを使用してオブジェクトを送信しています:

        private void SendDatabaseObj(Socket handler, IOrderedQueryable<BuildHistory1> buildHistoryQueryResult)
        {
            byte[] byteData = ObjectToByteArray(buildHistoryQueryResult);

            // Begin sending the data to the remote device.
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }

ObjectToByteArray()関数(送信する前にオブジェクトをシリアル化する):

        private byte[] ObjectToByteArray(Object obj)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, obj);
            return ms.ToArray();
        }

これを介して送信したオブジェクトを受信して​​います。

        private void ReceiveCallback_onQuery(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket 
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device.
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far. But how to store?

                    // Get the rest of the data.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback_onQuery), state);
                }
                else
                {
                    // All the data has arrived; put it in response.
                    if (dataReceived > 1)
                    {
                        //Use the deserializing function here to retrieve the object to its normal form
                    }
                    // Signal that all bytes have been received.
                    receiveDoneQuery.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

私の逆シリアル化関数:

        private Object ByteArrayToObject(byte[] arrayBytes)
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            ms.Write(arrayBytes, 0, arrayBytes.Length);
            ms.Seek(0, SeekOrigin.Begin);
            Object obj = (Object)bf.Deserialize(ms);
            return obj;
        }

今、私の質問は受信関数「ReceiveCallback_onQuery()」にあります。受信するデータがまだある場合、以前に受信したデータを保存するにはどうすればよいですか?

編集:私は以下のコードを実行することを知っていますが、受信したデータをbyte []変数に格納して、それらをIOrderedQueryableに戻すことができる他の方法があります

state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
4

2 に答える 2

0

IQueryableaをネットワーク経由で渡さないでください。反対側でクエリ機能を使用することはできません。代わりに、リクエスト (つまり、受け取る項目に関する情報を含む) と応答 (一致するオブジェクトの配列を含むオブジェクト) を表すクラスを作成します。

ネットワーク層を自分で処理したくない場合や、WCF よりも軽量なアプローチが必要な場合は、私の Griffin.Networking ライブラリを使用できます。

簡単なチャット クライアント/サーバーを 20 分で作成する方法を示すビデオをアップロードしました: https://www.youtube.com/watch?v=DjJOaV2y1Lo

サンプルコード: https://github.com/jgauffin/Samples/tree/master/Griffin.Networking/ChatServerClient

于 2012-11-19T13:25:51.530 に答える
0

ソケットなどを使用してデータをストリーミングする場合、各メッセージの開始と終了がデータのどこにあるかを知る何らかの方法をプロトコルに組み込む必要があります。これは、標準プロトコル用のツール (SOAP 用の WCF など) によって自動的に処理されますが、独自のプロトコルを設計する場合は、自分で実装する必要があります。最も簡単な方法は、既知の区切り文字または文字列を各メッセージ間に追加することですが、区切り文字がメッセージのデータ内に表示されないように注意する必要があります。もう 1 つの方法は、メッセージ ヘッダーでメッセージの長さを送信するか、単に固定長のメッセージを使用することです。

于 2012-11-19T12:11:36.573 に答える