【问题标题】:Passing and Receiving complex objects in C# Sockets [duplicate]在 C# 套接字中传递和接收复杂对象 [重复]
【发布时间】:2012-11-19 21:25:51
【问题描述】:

可能重复:
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));

【问题讨论】:

  • 您是否考虑过使用像 WCF 这样的现成解决方案,而不是发明自己的网络协议?
  • 您能详细说明一下吗?
  • WCF 是一个通信框架,它使用 SOAP 协议在服务器上执行远程过程并传递复杂的数据对象。 SOAP 是基于 XML 的,因此它可以轻松处理复杂的数据类型。如果这是您正在做的事情,那么创建 WCF 服务或简单的 asmx Web 服务将比您正在做的事情容易得多。例如,您可以使用 public void Submit(IOrderedQueryable&lt;BuildHistory1&gt; buildHistoryQueryResult) 之类的方法创建 WCF 服务,然后只需从客户端应用程序调用该服务上的方法。

标签: c# sockets asynchronous


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    如果您不想自己处理网络层并且想要一种比 WCF 更轻量级的方法,您可以使用我的 Griffin.Networking 库。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 2013-07-16
      相关资源
      最近更新 更多