【问题标题】:Reading From a TCP Socket从 TCP 套接字读取
【发布时间】:2019-04-02 21:53:36
【问题描述】:

我有客户发送一个非常简单形式的请求:只是字符串GET/PUT/INSERT/DELETE KEY <VALUE>,其中值是可选的,具体取决于所选的关键字。

键和值可以任意大小。

我正在用 C 语言实现一个服务器来为请求提供服务,但是我认为我遇到了 read() 系统调用读取一些但不是所有数据的问题。也就是说,服务器读取的只是客户端发送的一部分。

我如何知道整封邮件何时被阅读?

示例请求: INSERT KEYkeyKEYkeyKEY VALUEvalueVALUEvalueVALUE

但服务器可能会读取: INSERT KEYkeyKEYkeyKEY VALUEvalueVALUE

我怎么知道整条消息还没有被接收和阅读?

【问题讨论】:

  • 如果您指定客户端必须以回车符、NUL/零字节或客户端和服务器都同意的其他明确定义的字符来结束每个字符串,则表示行尾,那么您的服务器可以在其 TCP 输入流中查找该字符,并在看到它时解析前面的字符。

标签: c sockets tcp server


【解决方案1】:

TCP 不提供任何方式。 TCP 是一个面向流的协议,它所做的只是发送一个字节流。您可以在该流之上创建有线协议,以便检测消息边界。

经典方式

  • 发送具有预期消息大小的固定大小前缀
  • 使用自描述编码(例如 ber)
  • 发送分隔符 - 比如说文本协议中的 2 个空行(对于旧 RFC 协议很常见)

【讨论】:

  • * 发送分隔符,如(单个)\n 换行符...“旧” rfc 协议没有问题,它们统治着互联网 - 例如 http
  • 大量使用 CRLF 分隔的行/命令的协议(FTP、SMTP、POP3、IMAP、HTTP 等)仍在使用中
  • @RemyLebeau 和 barny 并没有贬低这些协议的意思。
【解决方案2】:

我怎么知道整条消息还没有被接收和阅读?

您需要一些约定来知道消息在哪里结束。你解析你的输入。

【讨论】:

    【解决方案3】:

    只是一个小提示:您正在经历短读。如前所述,通常您会添加一个包含消息长度的固定长度标头或解析消息的格式(假设接收 JSON 格式的字符串)。您还可以切换到基于消息的协议,例如 UDP 或 SCTP。

    另外请记住,理论上也可能发生长读取,即,您可以通过单个网络读取(或一个命令和另一个命令的一半)读取两个命令。

    【讨论】:

      猜你喜欢
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 2013-07-25
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多