How to find out a TCP server's status from the client side (In a redundant server case)?
I have a situation here. I have a redundant TCP server setup which takes an input and then throws lots of packets forever. While reading them, I am also trying to k开发者_如何学Goeep up with the server's state from TCP client by doing a send on the socket. But my servers are redundant sharing a Virtual IP. So if server1 goes down, server2 starts up and uses the same VIP (At all point of time VIP is up and running). So my send technique is able to find out this situation. My server2 waits for the client's input, but since send is not doing the job I expect it to do, I am not able to send the input again.
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
if ( status == -1 )
{
return false;
}
else
{
return true;
}
Can someone help how I can figure out this kind of failover?
Okay, piecing things together, I am starting to get a picture here.
- The OP is using some kind of failover in which the remote server doesn't actually keep track of the state
The reason you're not getting EPIPE from the send is that things happen this way:
- You
send
data.send
unblocks and segments start travelling - The remote server receives data. "Who is this guy ? RST!"
- You get the RST but
send
has already returned. The connection is torn but there is no way to inform you of it (it doesn't have any out-of-band mechanism) - Do another
send
In conclusion, if you want to test if a connection is still alive:
send
data- Wait a bit (RTT and such)
send
again
If you don't get EPIPE
after the second send
, the connection is still up. Another scheme:
send
data that should be interpreted as "Say something if you're alive!"- Wait a bit
- If after the timeout you haven't received confirmation, the connection is dead
A TCP session cannot be failed over from one server to another simply by the second server taking over the first's IP address - the TCP session state information must also be replicated from the primary server to the secondary, which requires special software.
Eventually the send to the server that has taken over must fail because that server won't know about the connection from the client IP:port, so it will issue an RST, which comes back as send() returning -1 and errno = ECONNRESET. This almost certainly won't happen on the first send after the failover because of asynchronicity and buffering.
精彩评论