I have troubles with my server application written in Python3/asyncio(Protocol), but I am pretty sure it's not much python or asyncio related, because I've tried different version also some 5liner just with the socket interface. It's about concurrent communication with many clients hardware TCP/IP<->RS232 converters. That's the reason asyncio is used, instead of threads with blocking write.
There is some periodic short data sending. The problem occurs when I physically cut the connection and wait for the exception to occur:
asyncio - Fatal read error on socket transport protocol
<_SelectorSocketTransport fd=11 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/selector_events.py", line 663, in
_read_ready
data = self._sock.recv(self.max_size)
OSError: [Errno 113] No route to host
It happens, but after 15 minutes, which means I am signaling for 15 minutes everything is alright, but it isn't, which is unbearably long and function breaking. Behavior checked in Ubuntu 16.04, Ubuntu 14.04 and Debian Jessie, all at different HW.
I found that (probably) kernel is buffering data, because if I reconnect device after ten minutes, all the data is flushed at once. I understand this is good for short disconnection, I would have no problem with 10s, 15s or even a minute, but 15 minutes is too much.
Similar question was answered by implementing application protocol, which is not possible in my case.
I just want to be sure the other side gets the packet (TCP ack) in some reasonable time.
I carefully read docs about socket.setsockopt
but didn't find anything useful. Also didn't find method how to check if send buffer was flushed to do some workarounds-manual detection of broken route.
TCP keep-alive is not helping either, because it's based on inactivity time and sending data is activity.