【问题标题】:Socket-connection: How does one end know that the other end received the message?Socket-connection:一端如何知道另一端收到了消息?
【发布时间】:2021-08-12 03:41:20
【问题描述】:

我有一个简单的套接字客户端-服务器应用程序。如果客户端通过套接字连接向服务器发出请求,当确认丢失时,它如何知道服务器收到了消息?我在以下情况下苦苦挣扎:

服务器接收客户端请求并开始处理消息。服务器向客户端发送一个确认,该确认可能永远不会到达客户端。客户端认为服务器没有收到消息。在这种情况下,我想防止客户端再次将请求发送到服务器,因为后者可能已经触发了每个请求只允许触发一次的进程。

【问题讨论】:

  • 为什么客户端因为没有收到服务器的响应就放弃了第一个请求?它仍然需要知道请求是否被处理,对吗?服务器知道,对吧?
  • @DavidSchwartz 因为它可能会阻塞等待可能永远不会到来的响应的线程(例如,服务器没有收到请求)
  • 无限期阻塞只是糟糕的设计。如果客户端做了一些愚蠢的事情,客户端应该被固定为不要仅仅因为服务器没有回复而放弃第一个请求,而是采取更适当的行动。

标签: java sockets


【解决方案1】:

如果来自服务器的响应(或确认)丢失,那么客户端将不知道服务器是否接收并处理了请求。在某些情况下,请求被处理两次不是问题,而在其他情况下却是。

解决这个问题的常用方法不是在客户端检查服务器是否成功接收到请求,而是在服务器检测重复请求并忽略这些请求。为此,请求需要有一些足够唯一的标识符,例如简单的请求计数器、事务 ID 或类似的。或者服务器可能会将请求本身视为唯一的 id,即会检测是否发送了两次完全相同的内容。

最佳实现取决于实际用例。但是例如 TCP 或 RTP 等协议的序列号会不断增加,因此服务器只需要记住最后一个进程号即可检测重复。

【讨论】:

  • 谢谢史蒂芬!我还考虑在服务器端对响应进行排队,以便客户端可以请求他们的响应,有点询问状态。但我猜这会导致太多的网络开销?那么,如果在客户端重新请求是超时后的默认过程,那么确认的价值是什么?
  • @cobby:我不确定我是否明白你在问什么。如果没有收到确认,则在超时后触发重传。只要没有收到确认,就会发生重传。所以仍然需要一个ack。但是服务器不应该两次处理同一个请求,这就是为什么它需要检测一个请求是否相同。
  • 我明白了,除了确认之外,我还在考虑特定响应的上下文,例如一条短信。我猜服务器必须暂时存储响应并在它没有再次收到相同的请求时丢弃它。如果它再次执行相同的请求,它会简单地使用早期请求中存储的响应进行响应。
猜你喜欢
  • 2017-08-16
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
相关资源
最近更新 更多