0

我对客户端和服务器之间的通信有疑问。我想通过 TCP unix 套接字发送数据(我知道如何做到这一点),但我不知道测试发送的消息是否可以完全读取(不是每个块的块)的最佳实践是什么。

因此,我在想这个

  1. 客户端发送格式化的数据 printf(3),消息被写入字符串并发送。
  2. 服务器收到消息,但如何确定消息是否已满?我需要循环直到消息完成吗?

所以我的想法是使用一个代码(或者可能是校验和?),它将被预先添加并附加到这样的消息中:

【验证码】 my_long_data_formatted 【验证码】

然后,服务器尝试读取数据,直到读取第二个验证码并成功检查。

这是客户端/服务器通信的正确解决方案吗?如果是,您对验证边界有何建议?

4

3 回答 3

4

TCP 已经有一个内置的校验和/验证。因此,如果消息被接收,则它被正确接收。

通常,您唯一需要担心的是弄清楚消息的长度。这可以通过在开头发送消息长度或在结尾放置终止字符或序列来完成。

可以说,为了确保发送者和接收者“在同一页面上”,接收者通常会在收到消息后发回响应,即使该响应只是说“OK”。

这种技术的示例包括 HTTP、SMTP、POP3、IMAP 和许多其他技术。

于 2012-11-21T14:47:06.173 回答
2

您需要建立一个应用程序级协议,它会以某种方式告诉您应用程序消息在 TCP 提供给您的字节流中的开始和结束位置(以及连接方如何进行对话)。

流行的选择是:

  • 固定长度的消息。适用于二进制数据并且非常简单。
  • 具有固定格式或大小标头的可变大小消息,可告知消息其余部分的确切大小(可能还有类型)。适用于二进制和文本数据。
  • 分隔消息 - 一些字符,如换行符或\x1特殊字符,表示消息边界。最好使用文本数据。
  • 自描述消息,如 XML、S 表达式或 ASN.1。
于 2012-11-21T15:12:36.737 回答
2

有几种方法可以做到这一点,所以我认为没有“正确”的解决方案。您的解决方案可能会奏效。需要注意的一点是,您需要确保您选择的验证代码不会作为消息中数据的一部分发送。如果是这种情况,您将检测到消息是完整的,即使它确实不是消息的结尾。如果无法知道数据的外观,您可能需要尝试不同的技术。

根据您的描述,听起来您的消息是可变长度的。另一种方法是使所有消息的长度相同,这样您就知道每次要读取多少数据才能获得完整的消息。

另一种方法是首先发送消息的长度(例如二进制 32 位数字),它指示在消息结束之前要读取的字节数。您首先读取它以获取数据量,然后从套接字读取该量。

如果您有一定数量的消息,每次长度都相同,您可以为每条消息分配一个编号,然后先发送该编号,然后您可以阅读该编号。使用该信息,您可以根据分配给消息的编号确定要读取多少数据。

您选择用于解决方案的内容可能取决于消息是否可变或长度固定和/或您是否需要随数据发送附加信息等因素。在这种情况下,您可能会混合发送一个固定长度的标头,其中包含有关随后数据的信息;无论是长度还是后面的数据类型。

于 2012-11-21T14:57:32.807 回答