TCP客户端问题

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

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

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

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

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

因此,您需要使用每条消息发送一些信息,以便您区分数据。 这通常通过每条消息开头的标记或类型数据来完成。 有时一个字节会起作用(取决于你有多少种不同的消息类型)。 然后,您从流中读取该字节,然后决定接下来要反序列化的内容。 例如,如果要发送字符串,可以序列化’1’,然后是string 。 如果要发送日期/时间,可以将“2”序列化为“日期时间”。 在服务器上,如果这两个对象大约在同一时间发送,您可以简单地反序列化该byte ,如果它是’1’,则反序列化一个string ,然后继续反序列化:获取下一个byte ,如果它是’2 ‘,反序列化DateTime

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

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

只需确保每条消息的长度都是前几个字节,这样就可以将整个消息拆分为单个消息。

例如,假设您从服务器收到此20字节消息:

  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 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ^ ^ ^ ^ ^ ^ 

第一个字节表示第一个消息有2个字节的数据,因此您可以将该消息作为字节1和2进行检索。接下来,您将读取字节3,它告诉您第二个消息只有1个字节的附加数据(字节4)。 第三个和第四个消息有3个字节的数据(如字节5和9所示),然后是2个字节的消息和3个字节的消息。

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

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

Interesting Posts