【问题标题】:C# UWP Socket: using ReceiveAsync / SendAsync and handling a timeout without closing the socketC# UWP Socket:使用 ReceiveAsync / SendAsync 并在不关闭套接字的情况下处理超时
【发布时间】:2018-02-18 06:03:18
【问题描述】:

我正在 UWP 平台上编写一个将用于移动 UWP 应用程序的类库。

库需要通过基于 TCP 的专有协议与外部设备通信。 该协议要求接收或发送操作等待一段准确的时间。

我实际上已经使用 ReceiveAsync 和 SendAsync 实现了通信层,“等待”它们,正如 TPL 模式建议的那样。

在大量阅读该论点后,我发现无法在本地设置读/写操作超时。 可以使用一些技巧来实现超时过程(例如:.WaitAny 或可超时的令牌),但我所有的阅读都让我明白了这个事实:

只有关闭套接字才能中断 ReceiveAsync 或 SendAsync 任务

我的问题是:这是真的吗? 只能关闭/处理套接字才能阻止超时的接收/发送?

如果这是真的,由于我正在实施的协议不允许我打开/关闭套接字数百次,我需要恢复到同步接收/发送版本实际处理优雅超时的命令。

我已经阅读了很多关于论点的内容,并且我很确定我所写的内容,但老实说,我希望有一种方法可以使用 TPL 模式来处理超时,而无需关闭套接字...

谢谢。

【问题讨论】:

    标签: c# sockets timeout sendasync


    【解决方案1】:

    我的问题是:这是真的吗?只能关闭/处理套接字才能阻止超时的接收/发送?

    是的,没错。超时不适用于异步套接字方法。取消现有异步读/写的正确方法是关闭套接字。

    如果这是真的,由于我正在实施的协议不允许我打开/关闭套接字数百次,我需要恢复到实际处理正常超时的命令的同步接收/发送版本.

    我不同意。协议定义中的超时只是建议性的;它们不能被强制执行。或者换一种说法,它不一定是 literal 接收或发送超时;它可以是逻辑“接收”或“发送”超时。

    【讨论】:

    • 感谢您的回复。我同意你的看法,超时是建议性的,但在这种情况下不是。我正在研究的协议是建立在非常便宜的硬件设备之上的(我想说的是物联网)。由于协议版本不一致或硬件问题或其他外部事件,设备可能不回复我的请求,将其丢弃而不回复 NACK 或其他错误状态。在这种情况下,协议需要我触发超时并尝试恢复。这是通信协议没有由软件工程师构建并且使事情变得有点复杂的典型情况。
    • 没关系。 当字节被传输到 OS TCP/IP 堆栈时,套接字“发送”完成 - 它们甚至可能还没有被发送到网络。回复当然不是超时。因此,在同步发送上应用超时无论如何都行不通。如我的回答中所述,您需要“逻辑”超时,同步和异步套接字 API 同样可以实现。
    • 什么是逻辑超时?您是在谈论进行非阻塞读取并计算读取返回 0 字节的时间吗?这可能是一个不错的解决方案。
    • 没有。在另一侧关闭套接字之前,读取不会返回 0 字节。我会不断地进行读取,然后定义一个逻辑“命令”操作,该操作表示发送的命令和接收的响应。这个“命令”是超时的操作,而不是套接字写入和读取。所以它的超时将由Task.Delay 或CancellationTokenSource.CancelAfter 控制,而不是实际的套接字读/写超时。
    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-07-12
    • 2019-03-21
    • 2013-10-04
    • 2020-01-10
    • 2012-04-06
    • 1970-01-01
    相关资源
    最近更新 更多