【问题标题】:TCP server: how to avoid message overlappingTCP 服务器:如何避免消息重叠
【发布时间】:2010-09-17 15:35:17
【问题描述】:

我要写一个 TCP 服务器,客户端给我发送 XML 消息,我想知道是否会发生以下情况以及如何避免这种情况:

1) 客户端发送<cmd ...></cmd> 2)服务器正忙于做某事 3) 客户发送<cmd ...></cmd> 4) 服务器执行 recv() 并将字符串放入缓冲区

如果我的缓冲区不够大,缓冲区是否会被<cmd ...></cmd><cmd ...></cmd> 或更糟的<cmd ...></cmd><cmd ... 填充?

我想要的是 TCP 堆栈将消息分成与客户端发送它们的方式相同的部分。

可行吗?

【问题讨论】:

标签: python networking tcp


【解决方案1】:

这在 TCP 级别是不可能保证的,因为它只知道流。

根据您使用的 XML 解析器,您应该能够将流提供给它并让它告诉您何时它有一个完整的对象,将第二个 <cmd... 留在其缓冲区中,直到它也被关闭。

【讨论】:

  • 你在说什么?由于每个客户端都有一个单独的套接字,所以描述的场景不可能发生。
  • 我可能误解了这个问题,但我假设场景是单个客户端,并询问对 send() 的调用是否直接映射到对 recv() 的调用
  • 是的,我认为这正是 OP 所要求的。
【解决方案2】:

您需要一个更高阶的协议来按您的意愿划分消息边界。还有plenty to choose from,包括你自己发明的那个。

【讨论】:

  • 实际上,问题不是数据序列化格式问题,因为看起来 OP 已经在使用类似 XML 的东西(XML 是该链接中建议的格式之一),问题是数据传输问题:如何知道文档何时完成。 HTTP 是一种可能的解决方案(未包含在您的链接中,事实上,该链接中的大多数格式都假定通过 HTTP 传输,而不是原始 TCP)。
【解决方案3】:

您经常以复数形式编写客户端:是否有多个客户端连接到您的服务器?在这种情况下,每个客户端都应该使用自己的 TCP 流,并且您所描述的问题永远不会发生。

如果各种命令是从单个客户端发送的,那么您应该编写客户端代码,以便它在发出下一个命令之前等待命令的响应。

【讨论】:

  • 那是垃圾 ;) 您只需要确保您的服务器正确处理消息帧。 TCP 是一个字节流,每次读取可以返回 1 和待处理的字节总数之间,所有 TCP 代码都应该处理这个。如果您在 TCP 之上有消息而不是基于流的协议,那么您需要实现某种形式的消息框架,以便将传入流拆分为您理解的消息。绝对没有必要将协议限制为严格的单个消息响应序列。即使您确实限制了您的客户,您也必须处理不完整的“消息”。
  • 我承认。第二段过于简化。但第一段回答了 OP 的一个重要问题。
  • “第二段过于简化”?怎么会这样?这是一个通用协议。这就是——例如——HTTP 的工作方式。
  • 简化的是客户端在发出另一个答案之前等待对请求的回答的方法。可以考虑其他协议,其中客户端可以在请求后发出请求,并异步获取答案。在客户端需要发送大量请求的情况下,这将大大减少延迟。
  • 为什么要制定一个新协议?这个问题似乎很简单。因此,第二段不能“过度简化”。 很简单。为什么要发明复杂性?我认为您的回答非常好,没有关于“过度简化”的所有胡扯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 2023-04-06
相关资源
最近更新 更多