3

假设我有一个客户端计数器变量。当我向服务器发送请求时,我发送此变量的值,然后将其加一(用于对服务器的下一个请求)。服务器独立地跟踪这个计数器,并检查以确保客户端发送的计数比它自己的(服务器端)计数副本多 1。这一切都很好,但考虑以下情况:

  1. 例如,客户端向服务器发送 23。
  2. 服务器收到 23,对其进行验证,然后将自己的计数器增加到 23。
  3. 服务器返回 All-Okay 代码给客户端

-但-

从服务器到客户端的过程中,返回代码被破坏。客户端因此认为服务器没有更新其计数器,因此将客户端计数器保留为 23。从这一点开始,客户端和服务器不同步。

有没有人知道面对这种可能的腐败/错误时可以使用的任何强大的方案?

谢谢,
卡梅伦

4

3 回答 3

2

您可以使用 64 位或更多熵的随机“nonce”值,而不是使用线性递增的计数器。当服务器收到来自客户端的请求时,服务器会检查随机数是否与它发送给客户端的最后一个随机数匹配。如果是这样,则处理请求并且服务器生成一个新的随机 nonce 值以在响应中发送。

服务器可以保留最后两个 nonce 值以发送给客户端。如果客户端发送旧值,则服务器假定发送给客户端的最新消息可能已丢失。

上述方法假设您的目标是防止两个不同的客户端使用相同的凭据与服务器进行通信。使用 nonce 方法的优点是下一个值不容易预测。

于 2008-10-18T23:19:25.687 回答
1

简单的答案是让客户端或服务器之一成为资源的所有者,而不是让两者都拥有自己的资源副本。

但是,如果您使用的是像 TCP 这样的可靠协议,则不必担心消息无法到达客户端。

但是,在进行客户端/服务器工作时要遵循的一件好事是使所有操作都具有幂等性。也就是说,每个函数都可以被调用一次或多次而没有任何副作用。在这种情况下,您根本没有“增量”功能。相反,您将拥有一个“设置”功能。

于 2008-10-18T23:16:01.357 回答
1

在服务器确认服务器计数器的更新之前不让客户端更新其本地副本怎么样。

所以:

客户端计算下一个值 客户端将下一个值发送到服务器 服务器检查下一个值是否有效(尚未看到) 服务器将计数器更新为下一个值(如果需要) 服务器通知客户端已收到下一个值 客户端将本地计数器更新为下一个值

如果服务器没有收到客户端更新,客户端只是重新发送计算的下一个值。如果客户端没有收到下一个值确认,它会重新发送下一个值,但是已经看到它的服务器不会更新,而只是确认。最终,客户端看到服务器的消息并继续。这涵盖了丢失消息的情况。

如果您担心损坏,请计算消息的校验和并将其发送。重新计算收到的校验和并将其与发送的校验和进行比较。不过,通常网络堆栈会为您执行此操作,因此除非您运行自己的协议,否则我不会太担心它。

于 2008-10-18T23:31:28.533 回答