在客户端和服务器之间同步一个变量

3
假设我有一个客户端计数器变量。当我向服务器发送请求时,我会发送这个变量的值,然后将其加1(为下一次向服务器发送请求做准备)。服务器独立地跟踪此计数器,并检查客户端发送的计数是否比它自己(服务器端)的计数多1。这一切都很好,但请考虑以下情况:
  1. 客户端发送23到服务器。
  2. 服务器接收到23,验证它,并将自己的计数器增加到23。
  3. 服务器向客户端返回“全部正常”的代码
- 但是 -
在从服务器返回到客户端的过程中,返回代码被损坏。因此,客户端认为服务器没有更新其计数器,因此将客户端计数器保留在23。从这一点开始,客户端和服务器就不同步了。
有人知道任何可靠的方案,可以应对这种可能的损坏/错误吗?
谢谢, 卡梅伦
3个回答

2

不要使用线性递增计数器,而是可以使用一个具有64位或更多熵值的随机"nonce"值。当服务器收到客户端请求时,服务器会检查nonce是否与上一次发送给客户端的相匹配。如果是,则处理请求并生成一个新的随机nonce值以在响应中发送。

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

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


是的,那是我的目标,但在我的特定情况下,数字的可预测性不会成为问题。我确实考虑过nonce的事情,但是方向完全不同;你的解决方案非常干净和快速。谢谢! - Cameron

1

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

如果您正在使用可靠的协议(如TCP),则无需担心消息无法传递到客户端。

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


1

不如这样,直到服务器确认了对服务器计数器的更新,客户端才更新其本地副本,怎么样呢?

所以:

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

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

如果您担心数据损坏,请在消息上计算校验和并将其一起发送。 收到消息后重新计算校验和并将其与发送的校验和进行比较。 通常,网络堆栈会自动完成此操作,所以除非您正在运行自己的协议,否则不用太担心。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接