在C#套接字中传递和接收复杂对象

时间:2012-11-19 12:00:47

标签: c# sockets asynchronous

  

可能重复:
  How to asynchronously receive complex object in 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));

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

如果你不想自己处理网络层,并希望比WCF更轻量级,你可以使用我的Griffin.Networking库。

我刚刚上传了一段视频,演示了如何在20分钟内创建一个简单的聊天客户端/服务器:https://www.youtube.com/watch?v=DjJOaV2y1Lo

示例代码:https://github.com/jgauffin/Samples/tree/master/Griffin.Networking/ChatServerClient