TCP客户端问题

时间:2012-09-10 12:52:22

标签: c# sockets tcpclient tcpserver

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

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

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

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

3 个答案:

答案 0 :(得分:5)

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

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

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

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

答案 1 :(得分:0)

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

例如,假设您从服务器收到此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个字节的消息。

答案 2 :(得分:-1)

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

如果您不想自己照顾好一切,可以使用像mine这样的网络库。向下滚动到文章末尾以查看JSON RPC示例实现。您可以将大部分内容用于获取基于JSON的通信渠道。