2

我在 c# 中的 TCP 客户端应用程序返回中面临一个大问题。正常情况下它工作正常,但在某些情况下服务器向特定客户端发送同时响应,所以这种情况下所有同时响应都作为单个消息在客户端接收。所以这种情况下客户端无法识别单个消息。因此,在这种情况下,我的客户端应用程序无法处理特定活动。是否可以在客户端读取单个消息?所以为了解决这个问题,我有一些选择,但我不知道这是否是正确的方法。

1- 在客户端使用固定长度的缓冲区(但我的消息是可变长度的)。

2-为每个响应消息添加分隔符。

如果有人知道解决此类问题的解决方案,请帮助我。

4

3 回答 3

5

TCP是基于流的,您从客户端获取数据流到服务器。如果您无法构建一个应用程序协议来确保发送的每条消息都是分开的(这对于 TCP 来说通常不是一个明智的想法),那么您需要“反序列化”您对流的期望。

因此,您需要在每条消息中发送一些允许您区分数据的内容。这通常在每条消息的开头使用标记或类型数据来完成。有时一个字节就可以了(取决于你有多少不同的消息类型)。然后,您从流中读取该字节并决定接下来要反序列化什么。例如,如果你想发送一个字符串,你可以序列化 '1',然后string. 如果要发送日期/时间,可以序列化 '2' 然后DateTime. 在服务器上,如果这两个对象几乎同时发送,您可以简单地反序列化byte,如果是 '1',反序列化 a string,然后继续反序列化:获取下一个byte,如果是 '2',反序列化一个DateTime

重要的是要记住 TCP 是基于流的协议,而不是基于消息的协议。基于消息的需要在应用程序级别实现——例如上面的东西。

“序列化”和“反序列化”是指典型的内置序列化器和反序列化器,如.NET 文档中的序列化对象中所述。对于 JSON.NET 等库中包含的 JSON 序列化程序或内置的DataContractJsonSerializerJavaScriptSerializer.

于 2012-09-10T13:06:32.890 回答
0

Just make sure that each message has its length as first few bytes, this way you can split the whole into single messages.

For example, suppose that you receive this 20 bytes message from your server:

                                       (1)                                     (2)
0   1   2   3   4   5   6   7   8   9   0   1   2   3   4   5   6   7   8   9   0

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 2 | 4 | 6 | 1 | 5 | 3 | 3 | 2 | 6 | 3 | 4 | 1 | 6 | 2 | 3 | 5 | 3 | 0 | 4 | 6 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  ^           ^       ^               ^               ^           ^
  • The first byte says that the first message has 2 bytes of data, so you can retrieve that message as bytes 1 and 2.
  • Next you read byte 3 which tells you that the second message has only 1 byte of additional data (byte 4).
  • The third and the fourth message have 3 bytes of data (as bytes 5 and 9 indicate), then there's a 2 bytes message and a 3 bytes one.
于 2012-09-10T13:35:48.543 回答
-1

使用至少包含正文​​长度的固定长度标头是最简单的方法。然后根据正文,您可能需要其他信息(例如类型名称,如果您想使用 JSON 之类的东西来序列化/反序列化实际消息)。

如果您不想自己处理所有事情,您可以使用像这样的网络库。向下滚动到文章末尾以查看 JSON RPC 示例实现。您可以利用其中的大部分来获得基于 JSON 的通信渠道。

于 2012-09-10T13:44:14.230 回答