Tcp客户端:如何关闭并重新连接它

本文关键字:重新连接 何关闭 客户端 Tcp | 更新日期: 2023-09-27 18:06:28

您好,感谢您的帮助。这次我想问一下TcpClient。我有一个服务器程序,我正在编写一个客户端程序。此客户端使用 TcpClient。它从创建一个新客户端开始

clientSocket=new TcpClient(); 

(顺便问一下,这会导致异常吗?以防万一我把它放在一个 try-catch 中,但我不确定这是否真的有必要(无论如何,后来我进入了一个循环,在这个循环中我连接到服务器

clientSocket.Connect("xx.xx.xx.xx",port);

然后我创建一个网络流

clientStream=clientSocket.GetStream();

然后开始通过读取等待来自服务器的数据。我知道这是阻塞,所以我也设置了一个读取超时(比如 1 秒(

无论如何,到目前为止一切顺利。稍后,如果我没有从服务器收到任何内容,我会尝试向其发送一些内容。如果这种情况持续发生 3 次,我想关闭连接并再次重新连接到服务器

(请注意,一个完全不同的问题是当服务器以某种方式关闭时,导致客户端中出现其他类型的错误 - 也许我稍后会问这个问题(

那么,我该怎么办?

 if(clientSocket.Connected)
            {
                Console.WriteLine("Closing the socket");
                clientSocket.Close();
            }

我关闭插座。循环完成,所以我再次转到开头并尝试连接到服务器。

clientSocket.Connect("xx.xx.xx.xx",port);

但是,这会导致错误(实际上是未处理的异常("无法访问已释放的对象"

所以我的问题是如何关闭并再次重新连接到服务器?

再次感谢您的任何帮助

Tcp客户端:如何关闭并重新连接它

一个TcpClient实例只能用于连接一次。您可以简单地实例化一个新的TcpClient,而不是尝试重新打开一个关闭的。

正如另一个答案中所解释的,一个TcpClient对象只能连接一次。如果要重新连接到服务器,则必须创建新的TcpClient对象并再次调用Connect()

也就是说,你的问题中有许多明显的误解:

  1. 首先也是最重要的一点,如果您打算再次尝试使用TcpClient对象,例如向服务器发送一些数据,则不应使用ReceiveTimeout。超时期限到期后,基础套接字将不再可用。

    如果要在服务器未向您发送数据时定期向服务器发送数据,则应使用异步 I/O(无论如何都应该这样做,尽管存在学习曲线(,并使用常规计时器对象来跟踪从服务器接收数据以来经过的时间。
  2. 构造函数TcpClient当然可以引发异常。至少,任何new引用类型对象的尝试都可能抛出OutOfMemoryException,在TcpClient的情况下,它最终会尝试创建一个本机套接字句柄,这也可能会失败。

    虽然所有 I/O 对象和方法都可能引发异常,但您应该只捕获有办法正常处理的异常。因此,在向代码添加 try/catch 块之前,请确定在出现异常时要执行的操作,以确保代码不会损坏任何数据并继续正常运行。通常不可能优雅地处理OutOfMemoryException(并且在任何情况下保护new的所有使用都是不切实际的(,但您当然可以捕获SocketException,这可能由构造函数抛出。如果抛出该异常,则应立即放弃创建和使用 TcpClient 的尝试,并向用户报告错误,以便他们可以尝试纠正阻止套接字创建的任何问题。
  3. 如果您的服务器预计会向您发送数据,而您没有收到数据,那么关闭连接并重试不太可能改善这种情况。这只会在服务器上造成额外的负载,使其更有可能无法响应。同样,一遍又一遍地发送相同的数据。您应该请求一次,等待服务器响应的时间尽可能长,如果在所需时间内没有收到响应,请向用户报告错误并让他们决定下一步该怎么做。

    请注意,在这种情况下,您可以使用 ReceiveTimeout 属性,因为如果您没有及时收到响应,您将要做的就是放弃连接,这很好。

很简单:

client.Close();
client = new TcpClient();
client.Connect(host, port);