配置插座ACK超时? [英] Configure socket ACK timeout?

查看:212
本文介绍了配置插座ACK超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有配置在一个插座预计将收到的ACK的发送的数据断定连接失败前的超时的方法?



我意识到这个可以在应用层进行为好,但因为我发送的每包反正ACK'd,我只是想,如果收到我的数据就知道了,用附加数据在应用层来完成同样的事情似乎浪费。 (。更何况,我特别的应用程序使用每字节收取蜂窝链接)



注意:按我刚才的问题 -
原因NetworkStream.Write什么样的条件来阻止 - 你不能依靠 .WRITE ,以确定数据抛出一个异常没有被正确传送。


解决方案

这是一个老问题,但它跟我打回家......正如你原来的问题提到,这应该在应用层完成。



我希望我的经验可能会有所帮助,因为我有相同的想法,因为你(甚至与其他开发者打在我的球队在这个坚持TCP应该得到的任务完成)。在现实中它很容易乱了TCP的无线连接,相互冲突的网络的MTU,有时执行不力的路由器/接入点,这ACK过早或在故障情况。而且因为TCP旨在从一个源传输到一个目的地,而不是真的保证全双工事务通信。



我花了数年为嵌入式工作设备制造商并写了一个完整的客户端 - 服务器系统中,在仓库无线条码终端。不是细胞在这种情况下,但无线网络可以是一样糟糕(但即使无线网络将被证明所需的任务没用)。仅供参考,我的系统仍然是可靠的生产后,今天近7运行多年,所以我觉得我的实现是相当稳健的(它经历了从工业生产机器/焊接/空气压缩机/小鼠咀嚼网络连线等常规干扰)。



了解问题



@rodolk发布了一些好的信息。 TCP ACK的水平并不一定对应1-1每个应用程序的网络传输(而且将总是不能是1-1,如果你发送大于网络的MTU或者即使纳格被禁用最大数据包大小等等)。





TCP&放大器的最终的机制; IP(传输层和网络层的)是保证在一个方向的流量输送(从源头到目的地)与最大重试次数的/ etc一些限制。应用交流的最终目的是全双工(双向)应用层通信坐在TCP之上/ IP。混合这些层并不是一个好的策略。想在TCP / IP之上的HTTP请求 - 响应。 HTTP不靠的TCP ACK来实现自己的超时等HTTP将是一个很大的规范研究,如果你有兴趣。



但是,让我们甚至假装它在做你想要什么。你总是在1传输发送小于1 MTU(或最大数据包大小)和接收正好1 ACK。介绍你的无线网络环境,一切变得更加复杂。可以有成功的传输和相应的ACK之间的故障<!/ P>

的问题是,在无线通信流的每个方向不一定等于质量或可靠性和可的基于对本地环境因素和无线装置的移动时间变化。



设备经常收到优于它们可以传输。是很常见的设备,以完美收到传输,具有某种ACK的被发送答复,但无线ACK信息不会到达其目的地,由于信号质量,传输距离远,射频干扰,信号衰减,信号反射,等在工业应用中,这可能是重型机械开启,熔接机,冰箱/冰柜,荧光灯等,在城市环境中,它可能是结构,车库,建筑钢结构等。

$ b $内的流动性b

在这种情况下哪一点客户采取行动(保存/提交数据或改变状态),并在什么时候服务器考虑行动成功(保存/提交数据或改变状态)?这是非常困难的可靠解决,而无需在应用层的附加通信检查(有时也包括对交易2路ACK即:客户端传输,服务器ACKS,客户端的ACK的应答:-)你不应该依赖于TCP ACK的水平在这里,因为他们就不能可靠地等同于成功的全双工通信,将不利于您的应用程序可靠的重试机制。



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



我们的技术是每个应用程序级消息与一对夫妇字节的应用层头,包括一个数据包ID#(只是一个递增的整数),长度发在字节整个消息和对整个消息的CRC32校验的。我不记得是肯定的,但我相信,我们在8个字节这样做,2 | 2 | 4.(根据您想要支持的最大消息长度)。



因此,让我们说你是在仓库计数的库存,你算一个项目,算上5个单位,条形码终端发送消息给服务器说奔计数5单位物品1234的。当服务器收到消息时,它会等到收到完整的消息,首先验证消息长度,然后CRC32校验(如果长度相匹配)。如果这一切过去了,我们发回的应用程序响应此消息(类似于应用程序的ACK)。在此期间,条形码终端正在等待来自服务器的ACK,并且如果它不听到从服务器返回将重发。如果服务器接收到相同分组ID的多个拷贝它可以取消重复通过放弃未提交的事务。但是,如果条形码扫描器并从服务器接收ACK,就那么多一个最后的提交命令到服务器答复。因为第2条消息刚刚确认了一个工作全双工连接,提交是令人难以置信的可能性不大这对夫妻毫秒的时间内失败。仅供参考,此故障情况是很容易在你的WiFi覆盖的边缘进行复制,所以需要你的笔记本电脑/设备和去散步直到WiFi是只是1栏或最低的连接速度通常为1Mbps。



所以要添加8个字节的头到邮件的开头,并选择性地加入一个额外的最后提交信息传输,如果你需要一个交易请求/响应时,只有无线的一面通讯可能会失败。



这将是很难自圆其说节省每封邮件的8个字节,一个复杂的应用层,传输层拦截系统(如挂钩到的WinPcap )。你也可能会或可能无法复制在其他设备上这个传输层挂钩(也许你的系统将在未来的其他设备上运行?的Android,iOS版的Windows Phone,Linux的,你能实现所有这些相同的应用程序层的通信平台?我认为你应该能够实现你每个设备上的应用程序,无论TCP协议栈是如何实现的。)



我建议你保持你的应用层分开的良好分离的关注,并在重试条件,超时和潜在的交易应用程序状态的变化严密控制传输层和网络层。


Is there a way to configure the timeout in which a socket expects to receive an ACK for sent data before it decides that the connection has failed?

I'm aware this can be done at the application level as well, but since every packet I send is ACK'd anyway, and I just want to know if my data is received, using additional data at the application level to accomplish the same thing seems wasteful. (Not to mention, my particular application uses per-byte charged cellular links.)

Note: As per my previous question -- What conditions cause NetworkStream.Write to block? -- you cannot rely on .Write throwing an exception in order to determine that data is not being sent properly.

解决方案

This is an old question, but it hits home with me... As alluded to in your original question, this should be done at the application layer.

I'm hoping my experience may be helpful as I had the exact same thoughts as you (and even fought with other developers on my team over this insisting TCP should get the job done). In reality its quite easy to mess up TCP with wireless connections, conflicting network MTUs and sometimes poorly implemented routers/access points which ACK prematurely or during failure conditions. But also because TCP is intended to stream from one source to one destination, not really to ensure full-duplex transacted communications.

I spent a number of years working for an embedded device manufacturer and wrote a complete client-server system for wireless barcode terminals in a warehouse. Not cellular in this case, but wifi can be just as bad (but even WiFi will prove the desired task useless). FYI, my system is still running reliably in production today after almost 7 years, so I think my implementation is reasonably robust (it experiences regular interference from industrial manufacturing machines/welders/air compressors/mice chewing network wires, etc).

Understanding the problem

@rodolk has posted some good info. TCP level ACKs do not necessarily correspond 1-1 with each of your application network transmissions (and will invariably NOT be 1-1 if you send more than the network's MTU or maximum packet size even if Nagle is disabled).

Ultimately the mechanisms of TCP & IP (Transport and Network layers) are to ensure delivery of your traffic in one direction (from source to destination) with some limits on maximum retries/etc. Application communication is ultimately about full duplex (two-way) Application layer communications that sit on top of TCP/IP. Mixing those layers is not a good strategy. Think of HTTP request-response on top of TCP/IP. HTTP does not rely on TCP ACKS to implement its own time outs, etc. HTTP would be a great spec to study if you are interested.

But let's even pretend that it was doing what you want. You always send less than 1 MTU (or max packet size) in 1 transmission and receive exactly 1 ACK. Introduce your wireless environment and everything gets more complex. You can have a failure between the successful transmission and the corresponding ACK!

The problem is that each direction of the wireless communication stream is not necessarily of equal quality or reliability and can change over time based on local environmental factors and movement of the wireless device.

Devices often receive better than they can transmit. It is common for the device to receive your transmission perfectly, reply with some kind of "ACK" which is transmitted, but that wireless ACK never reaches its destination due to signal quality, transmission distance, RF interference, signal attenuation, signal reflection, etc. In industrial applications this could be heavy machinery turning on, welding machines, fridges/freezers, fluorescent lighting, etc. In urban environment it could be mobility within structures, parking garages, steel building structures, etc.

At what point in this scenario does the client take action (save/commit data or change state) and at what point does the server consider the action successful (save/commit data or change state)? This is very difficult to solve reliably without additional communication checks in your application layer (sometimes including 2-way ACK for transactions ie: client transmits, server ACKS, client ACKS the ACK :-) You should not rely on TCP level ACKs here as they will not reliably equate to successful full duplex communication and will not facilitate a reliable retry mechanism for your application.

Application layer technique for unreliable wireless communications on embedded devices

Our technique was that every application level message was sent with a couple byte application level header that included a packet ID # (just an incrementing integer), the length of the entire message in bytes and a CRC32 checksum for the entire message. I can't remember for sure, but I believe we did this in 8 bytes, 2 | 2 | 4. (Depending on the maximum message length you want to support).

So let's say you are counting inventory in the warehouse, you count an item and count 5 units, the barcode terminal sends a message to the server saying "Ben counted 5 units of Item 1234". When the server receives the message, it would wait until it received the full message, verify the message length first, then CRC32 checksum (if the length matched). If this all passed we sent back an application response to this message (something like an ACK for the application). During this time the barcode terminal is waiting for the ACK from the server and will retransmit if it doesn't hear back from the server. If the server receives multiple copies of the same packet ID it can de-duplicate by abandoning uncommitted transactions. However if the barcode scanner does receives its ACK from the server, it would then reply with one more final "COMMIT" command to the server. Because the first 2 messages just validated a working full duplex connection, the commit is incredibly unlikely to fail within this couple ms timeframe. FYI, this failure condition is fairly easy to replicate at the edge of your WiFi coverage, so take your laptop/device and go for a walk until the wifi is just "1 bar" or the lowest connection speed often 1 mbps.

So you are adding 8 bytes header to the beginning of your message, and optionally adding one extra final COMMIT message transmission if you require a transacted request/response when only one side of the wireless communication might fail.

It will be very hard to justify saving 8 bytes per message with a complex application layer to transport layer hooking system (such as hooking into winpcap). Also you may or may not be able to replicate this transport layer hooking on other devices (maybe your system will run on other devices in the future? Android, iOS, Windows Phone, Linux, can you implement the same application layer communication for all these platforms? I would argue you should be able to implement your application on each device regardless of how the TCP stack is implemented.)

I'd recommend you keep your application layer separate from the transport and network layers for good separation of concerns, and tight control over retry conditions, time-outs and potentially transacted application state changes.

这篇关于配置插座ACK超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆