iOS Network Framework and TCP ZeroWindow

Hello,

I came accros a wired behaviour in my app, using local network.

My app is connecting to a local device, sending messages, and closing the tcp connection.

Sometimes (when the device handle lots of data) the device send TPC packets with a window size value of: 0.

But using the NWConnection (of the Network Framework) this is transparent, we have no clue about the window size, the system will send the data when the window size will update.

However, using NWConnection.send, we got the send completion closure being call without any error while the data has not been sent to the device.

So our app closes the connection (NWConnection.cancel) successfuly (data still to sent to the device).

If the TCP Window is updated, after that, while the app is still open, there is no issue, iOS sends the data to the device and then actually closes the TCP Connection.

But if the device is locked, or the app being sent to the background before the TCP Window Size is updated, then iOS sent a RST packet to the device and the connection terminates without the data ever reaching the device. From the app point of view, the data was sent and it seams that we have no way to informe the user that the message was not sent to the device.

Does any one have an idea of how the app can be aware of this data not sent to the device?

Thanks for your help!

Does any one have an idea of how the app can be aware of this data not sent to the device? So our app closes the connection (NWConnection.cancel) successfuly (data still to sent to the device).

Why does your app close the TCP connection in this context? Are you doing a send() while the window size is 0 on the device and the data does not reach the device, but your app assumes that it did and optimistically closes the connection?

If you are experiencing this problem, and control the device you are sending data to, you could build in your own acknowledgement behavior. While this is tedious, it would at least allow you to know that the device is aking 65bytes etc... and that each packet of data was received.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

Hello Matt,

Thanks for your answer.

Why does your app close the TCP connection in this context? Are you doing a send() while the window size is 0 on the device and the data does not reach the device, but your app assumes that it did and optimistically closes the connection?

Our app closes the TCP connection because only few connections are allowed simultaneously, so we do not need to "occupy" the device unnecessarily. This a "good practice" sent by the manufacturer of the device.

But I assume that we would have the same problem without closing the TCP connection right away. Because we need to close the connection anyway when the app is sent to the background, right?

If you are experiencing this problem, and control the device you are sending data to, you could build in your own acknowledgement behavior. While this is tedious, it would at least allow you to know that the device is aking 65bytes etc... and that each packet of data was received.

Sadly we do not control the device so we cannot build and acknowledgement system and are relying on the acknowledgement built-in the TCP protocol.

Thanks,

iOS Network Framework and TCP ZeroWindow
 
 
Q