【问题标题】:Server client message verification服务器客户端消息验证
【发布时间】:2012-11-09 20:08:38
【问题描述】:

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

所以我在想这个

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

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

[验证码] my_long_data_formatted [验证码]

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

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

【问题讨论】:

  • 如果您发送消息大小,那么您就知道要阅读多少,从而知道何时阅读完毕。

标签: c sockets unix tcp


【解决方案1】:

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

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

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

这种技术的示例包括 HTTP、SMTP、POP3、IMAP 等。

【讨论】:

  • 感谢您的回复,但即使消息比 TCP 最大数据包大,我也可以仔细读取数据(前面加上要读取的大小)?
  • @user840599 TCP 是面向流的协议,而不是面向数据包的协议。它如何被打包的细节对程序员是隐藏的。但是,是的,您通常会在接收调用中循环将数据推送到缓冲区中,直到您有足够的数据来满足您的要求
  • 谢谢,我明白了。现在我只需要写一个好的机制来阅读,直到消息已满。我认为线程可以解决问题。谢谢!
【解决方案2】:

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

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

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

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

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

【讨论】:

    【解决方案3】:

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

    流行的选择是:

    • 固定长度的消息。可以很好地处理二进制数据并且非常简单。
    • 具有固定格式或大小标头的可变大小消息,可告知消息其余部分的确切大小(可能还有类型)。适用于二进制和文本数据。
    • 分隔消息 - 某些字符(如换行符或 \x1)是特殊字符,表示消息边界。最适合文本数据。
    • 自描述消息,例如 XML、S 表达式或 ASN.1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2020-09-08
      • 1970-01-01
      相关资源
      最近更新 更多