c# – 配置套接字ACK超时?

栏目: C# · 发布时间: 5年前

内容简介:http://stackoverflow.com/questions/7667633/configure-socket-ack-timeout

在确定连接失败之前,是否有办法配置套接字期望接收发送数据的ACK的超时时间?

我知道这可以在应用程序级别完成,但是由于我发送的每个数据包都是ACK,我只想知道我的数据是否被接收,在应用程序级使用附加数据来完成相同的操作事情似乎很浪费. (更不要说,我的特定应用程序使用每字节充电的蜂窝链路.)

注意:根据我以前的问题 –

What conditions cause NetworkStream.Write to block? – 你不能依靠.Write抛出异常,以确定数据没有正确发送.

这是一个古老的问题,但它与我在一起回家…正如你原来的问题所暗示的那样,应该在应用层完成.

我希望我的经验可能是有帮助的,因为我有完全相同的想法(甚至与我的团队的其他开发人员争取这个坚持的TCP应该完成工作).实际上,它很容易使TCP与无线连接,冲突的网络MTU和有时执行不良的路由器/接入点过早地或在故障条件下进行.而且因为TCP旨在从一个源流传输到一个目的地,而不是真正地确保全双工处理的通信.

我花了几年时间为嵌入式设备制造商工作,为仓库中的无线条形码终端写了一个完整的客户端 – 服务器系统.在这种情况下不是蜂窝的,但是WiFi可以是一样糟糕(但即使WiFi将证明所需的任务无用). FYI,近7年来,我的系统在生产中仍然可靠运行,所以我认为我的实施是相当稳健的(经历工业制造机器/焊工/空气压缩机/老鼠咀嚼网络线等的干扰).

了解问题

@rodolk发布了一些很好的信息. TCP级别的ACK不一定对应于您的每个应用程序网络传输(如果发送超过网络的MTU或最大数据包大小,即使Nagle被禁用,也不一定是1-1).

> IP Datagram Size, the Maximum Transmission Unit (MTU), and Fragmentation Overview

> Dealing with Fragmented Traffic

> Wireless Networking MTU – Physical MTU vs Logical Packet Size

最终,TCP& IP( Transport and Network layers )将确保您的流量在一个方向(从源到目的地)交付,并且对最大重试次数有一些限制.应用通信最终涉及位于TCP / IP之上的全双工(双向) Application layer 通信.混合这些层不是一个好的策略.想想在TCP / IP之上的HTTP请求响应. HTTP不依赖TCP ACKS实现自己的超时等.如果你有兴趣,HTTP将是一个很好的规范.

但是我们甚至假装它正在做你想要的事情.您始终在1个传输中发送少于1个MTU(或最大包大小),并且正好接收1个ACK.介绍您的无线环境,一切都变得更加复杂.您可以在成功传输和相应的ACK之间发生故障!

问题是无线通信流的每个方向不一定具有相同的质量或可靠性,并且可以基于本地环境因素和无线设备的移动随着时间而改变.

设备通常比他们可以传输更好.设备接收传输是很常见的,用某种传输的“ACK”进行回复,但由于信号质量,传输距离,射频干扰,信号衰减,信号反射等原因,无线ACK无法到达目的地在工业应用中,这可能是重型机械开关,焊接机,冰箱/冷柜,荧光灯等.在城市环境中,可能是结构,停车库,钢结构建筑物等内的移动.

在这种情况下,客户端在什么时候采取行动(保存/提交数据或更改状态),以及服务器在何时认为操作成功(保存/提交数据或更改状态)?这在应用层中无需额外的通信检查就非常难以解决(有时包括用于事务的双向ACK,即:客户端发送,服务器ACKS,客户端确认ACK :-)您不应该依赖于TCP级别的ACK,因为它们将无法可靠地等同于成功的全双工通信,并且不会为您的应用程序提供可靠的重试机制.

嵌入式设备不可靠无线通信的应用层技术

我们的技术是每个应用程序级别的消息都被发送到一个包含数据包ID(只是一个递增整数)的字节应用程序级头,字节的整个消息的长度以及整个消息的CRC32校验和.我不记得了,但我相信我们这样做是8字节,2 | 2 | (取决于您要支持的最大消息长度).

所以假设你在仓库里盘点库存,你会计数一个项目并计数5个单位,条形码终端向服务器发送一条消息,说“本计算了5个单位的项目1234”.当服务器接收到消息时,它将等到接收到完整的消息,首先验证消息长度,然后验证CRC32校验和(如果长度匹配).如果这一切都通过,我们将回复应用程序的响应发送给该消息(类似于应用程序的ACK).在此期间,条形码终端正在等待来自服务器的ACK,并且如果没有从服务器回来,将重新发送.如果服务器接收到相同数据包ID的多个副本,则可以通过放弃未提交的事务来取消复制.然而,如果条形码扫描器从服务器接收到ACK,那么它将再次向服务器回复最后一个“COMMIT”命令.因为前两个消息刚刚验证了一个工作的全双工连接,所以提交在这几个ms时间段内难以想象. FYI,这种故障条件在您的WiFi覆盖的边缘很容易复制,所以拿你的笔记本电脑/设备去散步,直到WiFi只是“1 bar”,或最低的连接速度通常是1 mbps.

所以你要在消息的开始添加8个字节的头,如果只需要一个无线通信的一方可能会失败,可以选择添加一个额外的最后的COMMIT消息传输.

通过复杂的应用层保存每个消息的8个字节来传输层挂钩系统(例如挂接到winpcap)将是非常困难的.此外,您可能或可能无法复制挂在其他设备上的传输层(也许您的系统将来会在其他设备上运行?Android,iOS,Windows Phone,Linux可以为所有这些实现相同的应用层通信平台?我认为您应该能够在每个设备上实现应用程序,而不管TCP堆栈如何实现.)

我建议您将应用层与运输和网络层分开,以便很好地分离问题,并严格控制重试条件,超时和可能处理的应用程序状态更改.

http://stackoverflow.com/questions/7667633/configure-socket-ack-timeout


以上所述就是小编给大家介绍的《c# – 配置套接字ACK超时?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人人都是产品经理

人人都是产品经理

苏杰 / 电子工业出版社 / 2010年4月 / 45.00元

这是写给“-1到3岁的产品经理”的书,适合刚入门的产品经理、产品规划师、需求分析师,以及对做产品感兴趣的学生,用户体验、市场运营、技术部门的朋友们,特别是互联网、软件行业。作为一名“4岁的产品经理”,作者讲述了过去3年的经历与体会,与前辈们的书不同,本书就像你走到作者身边,说“嗨哥们!晚上有空吃个饭么,随便聊聊做产品的事吧”,然后作者说“好啊”。 书名叫“人人都是产品经理”,是因为作者觉得过......一起来看看 《人人都是产品经理》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具