-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

当流式传输数据时,例如使用套接字,您必须在协议中内置某种方式来了解每条消息的开始和结束在数据中的位置。这由标准协议的工具(例如用于 SOAP 的 WCF)自动处理,但如果您要设计自己的协议,则需要自己实现它。最简单的方法是在每条消息之间添加一个已知的分隔符或字符串,但是您需要注意分隔符永远不会出现在消息的数据中。另一种选择是在消息头中发送消息的长度,或者简单地使用固定长度的消息。

于 2012-11-19T12:11:36.573 回答
0

不要通过IQueryable网络传递。您不能使用另一侧的查询功能。而是创建一个表示请求(即包含有关要接收哪些项目的信息)和响应(包含匹配对象数组的对象)的类。

如果您不想自己处理网络层并且想要一种比 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 回答