How do I disconnect a TcpClient to allow new connections?
I have a TcpListener which waits for new socket connections. When a new connection is made, some other code services messages from the remote user. I periodically check for new connections and if a new one is made, the old one should be dropped.
Previously I'd just open the new connection which for the most part worked okay. Occasionally though, I'd have problems re-using the same port so I figured it would be better to close that connection (which I think should also give the old user an indication that the connection died).
The code below is my attempt to do that, but for some reason the Disconnect call seems to block indefinitely. Is there a way of stopping that? ...or am I missing something else here?
while(1)
{
// FYI, m_server is a TcpListener^ and m_client is a TcpClient^
// Check for new client connections
if (m_server->Pending() == true)
{
if( m_stream != nullptr )
{
m_client->Client->Shutdown( SocketShutdown::Both ); // Stop sending / receiving
m_client->Client->Disconnect(true); // Disconnect the underlying network stream
m_client->Client->Close(); // Disconnect the underlying network stream
m_client->Close();
delete m_client;
m_client = nullptr;
}
m_client = m_server->AcceptTcpClient(); //grab the TCP client
m_stream = m_client->GetStream(); //create the stream at the same time
}
// ...go and service pending messages on the client stream
}
The docs on the Disconnect() function suggest there's a timeout I can set but they don't mention how?
If you need to call Disconnect without first calling Shutdown, you can set the DontLinger Socket option to false and specify a nonzero time-out interval to ensure that data queued for outgoing transmission is sent. Disconnect then blocks until the data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.
[Edit] I found a solu开发者_如何学编程tion to the timeout problem by changing m_client->Client->Disconnect(true);
to m_client->Client->Disconnect(false);
but that still doesn't warn my client that the socket has closed. I've tried everything I can think of to test but they all succeed:
// m_client is a TcpClient^
bool stillConnected = ( (m_client != nullptr) &&
(m_client->Connected == true) &&
(m_client->Client != nullptr) &&
(m_client->Client->Connected == true) );
stillConnected
is always true even after another client has connected to the server and therefore called all the shutdown bits and pieces above. It's like the shutdown stuff I mentioned at the top of my question isn't closing the socket properly or something?
Disconnection of a TCP socket (FIN
flag being sent from the remote end) is detected when a read returns success and a length of zero bytes.
精彩评论