首页 > 解决方案 > 即使在客户端 ShutDown() 之后,Socket.Receive 也会阻塞

问题描述

我有一个带有套接字监听的服务器应用程序:

server = new TcpListener(myEndPoint);

// etc.

socket = server.AcceptSocket();

while (true) {

    int size = socket.Receive(data); // application waits here for data.

    if (size == 0)
    {
        // handle disconnect
    }
    else
    {
        // process data.
    }
}

现在客户端应用程序连接到这个......

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

socket.Connect(remoteIp, remotePort);

发送数据,完成后调用

socket.ShutDown(SocketShutdown.Both);

此时,我希望阻止 at 的服务器socket.Receive(data)继续进行,但 asize为 0。

根据此页面:

https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.receive?view=netframework-4.7.2

如果远程主机使用 Shutdown 方法关闭了 Socket 连接,并且已经接收到所有可用数据,则 Receive 方法将立即完成并返回零字节。

但它永远在这里等着。

有趣的是,如果我使用 PuTTY 连接到服务器应用程序,然后关闭 PuTTY,那么该Receive()方法完成并返回size= 0。PuTTY 在做什么而我不是?

注意:我也尝试TcpClient在客户端应用程序上使用 a ,但这有同样的问题。

标签: c#sockets

解决方案


原来这是我的错,我会把它留在这里以防其他人有同样的问题。

在尝试 Minu 的建议时,我注意到如果我在没有发送数据的情况下关闭套接字,则Receive()正确完成。

事实证明,在我的代码的其他地方,我让服务器在收到完整的数据后发回确认。但是,客户端接收确认的方法中有一个错误,导致它不能完全从套接字接收它,因此套接字上仍然有 7 个字节Available,这就是它没有关闭的原因。


推荐阅读