【问题标题】:About handling TCP connection when packet loss or connection broken关于在丢包或连接断开时处理 TCP 连接
【发布时间】:2013-10-10 13:22:01
【问题描述】:

我有用 C# 编写的 TCP 服务器和客户端。由于我的连接是通过不可靠的 wifi 连接的,所以我使用重新发送相同的数据包并处理数据包丢失。

例如银行账户平台。用户存款,客户端发送此消息给服务器,如果服务器收到此消息,将回复客户端操作成功。如果客户端没有收到回复,会在一段时间后再次发送。

这看起来很简单,但是当 wifi 卡住并且客户端没有收到回复并继续向服务器发送相同的消息时,我遇到了这种情况。最终这些消息同时被服务器接收。结果服务器认为用户存了 100 次钱。

我想知道人们通常如何处理 tcp 服务器客户端程序的这种情况,特别是当应用程序不仅仅是一个聊天应用程序,而是更敏感的信息,比如钱。我的第一个想法是在消息中添加一个事务 ID,这样服务器就不会处理具有相同事务 ID 的消息,这将防止上述情况。但不确定是否有更好的解决方案或.Net 对此有一些内部功能。

谢谢。

【问题讨论】:

    标签: c# tcp wifi reliability


    【解决方案1】:

    当您使用 C# 编写代码时,您主要是在 Application layerOSI model 中工作。 TCP 协议适用于Transport layer(位于应用层之下)。

    您想要实现的可靠性已经嵌入 TCP 协议本身。这意味着,如果某些数据包丢失,它将自动尝试重新发送数据包,而无需您的额外请求。这也将发生在控制权返回给应用层程序之前。还有other guarantees,比如包包的有序投递。

    这意味着,您需要的功能已经在下面的层实现,您无需担心。

    注意,如果您要使用UDP,您需要自己处理可靠性问题。

    【讨论】:

    • 那么你是说我同时收到这 100 条消息的情况是 C# 的工作,它帮助我重新发送了这些消息?
    • 之所以实现重发消息功能,是因为我在测试程序的时候,服务器端程序出现了一些错误,所以我关闭了它,重新执行。结果客户端程序卡住了,因为它没有收到回复并继续等待。甚至只是运行服务器程序的计算机意外关闭,需要重新启动。如果我不使用重新发送消息功能,我应该如何处理这些情况?
    • @AkariKamigishi 抱歉离开了。该协议提供了足够的保证来传递消息。您需要处理的是您在客户端或服务器端看到的特定错误。超时是一种常见的应用程序级技术 - 当无法访问远程应用程序时,发起者应定义并处理超时。
    • @如果计算机停机,您应该定义一个超时,这通常在所有默认通信调用中都可用。如果一个send(data, timeout)超时,它会抛出一个TimeoutException,你可以根据业务逻辑来处理,例如1分钟重发数据,尝试5次,如果不成功则终止。 TCP 协议确保消息只传递一次,如果无法传递,它会先死掉,然后您才会收到无法访问主机的通知。所以不要担心底层的东西,处理应用程序级别的错误
    • 应用程序级错误包括:超时、事务提交/回滚、主机停机一段时间(几分钟)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2021-03-25
    • 2014-09-06
    • 2015-11-06
    相关资源
    最近更新 更多