I have a TCP server that I unfortunately have no control over other than enabling/disabling TcpKeepAlive for it. This server only accepts one connection at a time. Due to the nature of project that I'm working on, I need to handle the case where the network link (ethernet cable in my case) goes down and comes back up after some time.
Here's what a succesful connect/disconnect operation looks like on WireShark.
1 0.000000 192.168.3.200 192.168.3.39 TCP 66 53805 → 6000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
2 0.001496 192.168.3.39 192.168.3.200 TCP 60 6000 → 53805 [SYN, ACK] Seq=0 Ack=1 Win=11680 Len=0 MSS=1460
3 0.001544 192.168.3.200 192.168.3.39 TCP 54 53805 → 6000 [ACK] Seq=1 Ack=1 Win=64240 Len=0
---====== sending/receiving data ======---
4 0.001577 192.168.3.200 192.168.3.39 TCP 54 53805 → 6000 [FIN, ACK] Seq=1 Ack=1 Win=64240 Len=0
5 0.003028 192.168.3.39 192.168.3.200 TCP 60 6000 → 53805 [ACK] Seq=1 Ack=2 Win=11680 Len=0
6 0.004735 192.168.3.39 192.168.3.200 TCP 60 6000 → 53805 [FIN, ACK] Seq=1 Ack=2 Win=11680 Len=0
7 0.004747 192.168.3.200 192.168.3.39 TCP 54 53805 → 6000 [ACK] Seq=2 Ack=2 Win=64240 Len=0
Now, the problem is that if I remove the ethernet cable and try to send/read something I immedialtey get a ECONNRESET error. When I plug the ethernet cable back in, since the server never got the FIN packet and can only accept one connection at a time, it doesn't let me connect and responds back with a RST, ACK packet.
3 10.732483 192.168.3.200 192.168.3.39 TCP 66 60231 → 6000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
4 10.734207 192.168.3.39 192.168.3.200 TCP 60 6000 → 60231 [SYN, ACK] Seq=0 Ack=1 Win=11680 Len=0 MSS=1460
5 10.734257 192.168.3.200 192.168.3.39 TCP 54 60231 → 6000 [ACK] Seq=1 Ack=1 Win=64240 Len=0
---====== sending/receiving data ======---
---====== ethernet cable is removed ======---
32 14.762503 192.168.3.200 192.168.3.39 TCP 75 60231 → 6000 [PSH, ACK] Seq=85 Ack=109 Win=64132 Len=21 [TCP segment of a reassembled PDU]
35 14.969724 192.168.3.200 192.168.3.39 TCP 75 [TCP Retransmission] 60231 → 6000 [PSH, ACK] Seq=85 Ack=109 Win=64132 Len=21
---====== ethernet cable is back in ======---
68 183.833820 192.168.3.200 192.168.3.39 TCP 66 61865 → 6000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
69 183.834797 192.168.3.39 192.168.3.200 TCP 60 6000 → 61865 [RST, ACK] Seq=1 Ack=1 Win=64240 Len=0
70 184.343851 192.168.3.200 192.168.3.39 TCP 66 [TCP Retransmission] [TCP Port numbers reused] 61865 → 6000 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
71 184.344126 192.168.3.39 192.168.3.200 TCP 60 6000 → 61865 [RST, ACK] Seq=1 Ack=1 Win=64240 Len=0
What is the proper way of handling this so that I can reconnect back immediately after the link is up?