TCP Socket 未正确关闭

Posted

技术标签:

【中文标题】TCP Socket 未正确关闭【英文标题】:TCP Socket not getting closed disposed properly 【发布时间】:2015-09-01 20:12:52 【问题描述】:

我有一个静态方法

public class TelnetClient

    public static string SendAndReceiveData2(string data, string HostIPAddress, int Port)
    
        using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        
            socket.Connect(HostIPAddress, Port);
            byte[] bytesToSend = Encoding.ASCII.GetBytes(data);
            socket.ReceiveTimeout = 3000;
            socket.SendTimeout = 3000;
            int bytesSent = socket.Send(bytesToSend);
            if (bytesSent != bytesToSend.Length)
            
                throw new Exception("Invalid send byte number");
            


            byte[] bytesReceiveBuffer = new byte[1024];
            int bytesRec = socket.Receive(bytesReceiveBuffer); //No need to loop for testing
            string returnedData = Encoding.ASCII.GetString(bytesReceiveBuffer, 0, bytesRec);

            socket.Close(); // Just out of desperation
            socket.Dispose();
            return returnedData;
        
    
 

我就是这样称呼它的:

for (int i = 0; i < 10; i++)

    TelnetClient.SendAndReceiveData2("some data different each time", "127.0.0.1", 1234);

我在循环中调用这个方法。此方法将一些命令发送到第三方应用程序,该应用程序立即返回响应。问题是此代码适用于第一次迭代,但在第二次迭代中,它在 socket.Receive 失败并出现错误:

连接尝试失败,因为连接方没有 一段时间后正确响应,或建立连接 失败,因为连接的主机没有响应。

这是棘手的部分,如果我没有循环多次,而是关闭 exe 并通过命令提示符重新开始,我没有收到错误,并且第三方应用程序也收到了多个请求。

这让我相信 套接字在循环中没有得到正确处理。但是如果我关闭进程再重新开始,就没有问题了。

我检查了socket.LocalEndPoint 每次都指向不同的端口。在第二次迭代中,socket.Available 也设置为 0

我不太确定发生了什么,如果有任何帮助,我将不胜感激。

【问题讨论】:

贴出调用该方法的代码。基本上没问题,错误在其他地方。不过,你可以删除那个迷信的三重结束代码。 @usr,刚刚发布了。 @usr,基本上在循环中的每次迭代中,我都会发送不同的字符串数据,(不同的命令集)。 代码没问题。服务器在运行什么代码? @usr,即第三方应用,通过TCP连接提供命令接口。 【参考方案1】:

我注意到您正在执行 Socket.Connect,但从未执行 Socket.Disconnect。

来自 MSDN 网站的Socket.Disconnect 将允许重用套接字并关闭连接。

【讨论】:

【参考方案2】:

Socket 和 Socket 的处理没有任何问题。错误消息有点误导。问题出在服务器端。

更多细节......

在第二次迭代中发送了无效数据,当我尝试发送与第一次迭代完全相同的数据时,它也失败了,因为对于每个请求,服务器都需要一个唯一的 Guid id。 Guid 是在循环外生成的,因此它被用于迭代中的所有项目。重新启动该过程正在工作,因为这样我会在第一次迭代中获得一个新的Guid

【讨论】:

以上是关于TCP Socket 未正确关闭的主要内容,如果未能解决你的问题,请参考以下文章

C |套接字未正确关闭

字节顺序宏未正确定义[关闭]

IOCP怎么正确关闭socket

关闭和清理 Socket 连接的正确方法是啥?

IOCP怎么正确关闭socket

在Python中,当在localhost上接受TCP套接字连接时,无法获得正确的对等体IP地址。