I've implemented async sockets using SAEA in the canonical way:
I've discovered an issue to do with network outages. Specifically, the sendAsync completion event does not fire when there's an outage , so my pool doesn't get refilled. This eventually ends up crashing the program, as it will run out of SAEAs, regardless of the size of the pool.
How do you avoid this? You can't simply keep a reference to an old SAEA, because that will give you an exception saying it's already waiting for an operation.
I'm looking for a way to gracefully replace the SAEAs. It's not a problem that the data does not get transmitted. One potential route to go is to run shutdown on the socket once a certain number of objects are waiting. Does anyone have experience of this?
It can indeed happen that no completion is posted in the case of basically infinite network latency (as would be the case when a cable is cut).
The only way to recover from such a problem is to implement some version of a heartbeating scheme. The SO_KEEPALIVE option exists on sockets but the default behavior is not usually what you want. From MSDN :
For TCP, the default keep-alive timeout is 2 hours and the keep-alive interval is 1 second.
I would suggest implementing your own heartbeating scheme, and consider the connection "dead" if no response heartbeat is received within a reasonnable amount of time. For example, you could :
The proposed solution does indeed work. It's simply a matter of checking before each send whether some limit is exceeded, and shutdown+close the socket if it is. This prevents the objects from leaking, allowing graceful reconnection later on.
I tested this by unplugging my cable and reconnecting repeatedly. In the old case the pool would empty. Now it survives the network outage.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.