关闭套接字会导致TIME_WAIT挂起状态

时间:2017-11-28 10:06:28

标签: sockets tcp client-server state

我正面临使用套接字客户端/服务器的一些问题。

在我的套接字流程中,我在发送响应后在服务器端关闭:

private static void Send(Socket handler, String data)
{
    try
    {
        // Convert the string data to byte data using ASCII encoding.
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.
        handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
    }
    catch { }
}

private static void SendCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the socket from the state object.
        Socket handler = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.
        int bytesSent = handler.EndSend(ar);
        Console.WriteLine("Sent {0} bytes to client.", bytesSent);

        handler.Shutdown(SocketShutdown.Both);
        //handler.Dispose();
        handler.Close();



    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

在客户端,我在从服务器读取答案后调用了关闭套接字函数:

var cc = new AsynchronousClient("192.168.1.201", 11001);
var er = cc.echo();
cc.closeConn();

public void closeConn(){
    sc.Close();
}

public void Close()
{
    if (socket != null && IsConnected)
    {
        OnClosed(this, EventArgs.Empty);
        IsConnected = false;

        socket.Close();
        socket = null;
    }
}

在服务器和客户端调用呼叫后,使用TCPView,我可以看到端口处于TIME_WAIT状态。我尝试了其他解决方案,比如使用Dispose,Disconnect和其他快速解决方案,但似乎没有任何东西强制关闭连接并在通信结束时释放端口。

看这个图像,我可以看到TIME_WAIT是真正关闭套接字之前的最后一个状态。

例如,我也尝试关闭仅服务器端的连接。我得到的是CLOSE_WAIT状态和FIN_WAIT2状态的服务器阻塞的客户端。所以,在TIME_WAIT之前的一步。

在某种程度上,我认为,我必须发送最后一个ACK以从TIME_WAIT传递到CLOSED。我怎样才能达到目标?

enter image description here

更新

我在服务器端试过这个:

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

// Bind the socket to the local endpoint and listen for incoming connections.
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
listener.Bind(localEndPoint);
listener.Listen(100);

1 个答案:

答案 0 :(得分:0)

解决方案是使用Windows API。

这里是代码:

[DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int closesocket(IntPtr s);

电话是

closesocket(socket.Handle);

我只在一边打电话,而不是两者。经过TCPView的长期分析后,我可以说它按预期工作。