1

In a TCP Socket server, if the server accepts a connection from a client then shuts down the socket associated with the client connection, the client can still send data to the server. No exception is raised by the client.

Why doesn't shutting down this socket cause an exception on the client-side?

I'd expect the client to attempt the send, realize it is no longer connected to a server socket then raise an exception. Obviously, this isn't happening which means either my assumption about how sockets should work here is incorrect (quite possible) or my code (below) is wrong. :-)

public async Task Demo()
{
    var endPoint = new IPEndPoint(IPAddress.Loopback, 2100);
    var serverTask = Task.Run(() =>
    {
        using (var listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
        {

            listenSocket.Bind(endPoint);
            listenSocket.Listen(backlog: 1);

            using (var connectionSocket = listenSocket.Accept())
            {
                connectionSocket.Shutdown(SocketShutdown.Both);
                connectionSocket.Close();
            }
        }
    });

    using (var clientSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
    {
        clientSocket.Connect(endPoint);

        await serverTask;

        // Expect this to throw a SocketException--but it doesn't.
        clientSocket.Send(new byte[] { 01 });
    }
}
Ben Gribaudo
  • 5,057
  • 1
  • 40
  • 75
  • 1
    This isn't a C# or .NET question. It's just about how sockets work, and the marked duplicate explains what you see. Short version: if the remote endpoint forcibly breaks the connection, it takes a write operation to notice that. Your first `Send()` call just causes data to be buffered...there was never any guarantee the data was received, and reporting of errors may (and often are) delayed. – Peter Duniho Dec 20 '17 at 18:50

1 Answers1

0

Socket closing is not a "bang!!!" instant action. Calling shutdown/close just indicates your intent to terminate the connection. Actual disconnect can happen after arbitrary amount of time (depends on a lot of things, especially for loopback connections).

Try the following: wrap your Send() into while(true) loop. Your very first iteration could be OK, then you end up with SocketException.

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42