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);
但是,这会导致错误(实际上是未处理的异常("无法访问已释放的对象"
所以我的问题是如何关闭并再次重新连接到服务器?
再次感谢您的任何帮助
一个TcpClient
实例只能用于连接一次。您可以简单地实例化一个新的TcpClient
,而不是尝试重新打开一个关闭的。
正如另一个答案中所解释的,一个TcpClient
对象只能连接一次。如果要重新连接到服务器,则必须创建新的TcpClient
对象并再次调用Connect()
。
也就是说,你的问题中有许多明显的误解:
- 首先也是最重要的一点,如果您打算再次尝试使用
TcpClient
对象,例如向服务器发送一些数据,则不应使用ReceiveTimeout
。超时期限到期后,基础套接字将不再可用。
如果要在服务器未向您发送数据时定期向服务器发送数据,则应使用异步 I/O(无论如何都应该这样做,尽管存在学习曲线(,并使用常规计时器对象来跟踪从服务器接收数据以来经过的时间。 - 构造函数
TcpClient
当然可以引发异常。至少,任何new
引用类型对象的尝试都可能抛出OutOfMemoryException
,在TcpClient
的情况下,它最终会尝试创建一个本机套接字句柄,这也可能会失败。
虽然所有 I/O 对象和方法都可能引发异常,但您应该只捕获有办法正常处理的异常。因此,在向代码添加try
/catch
块之前,请确定在出现异常时要执行的操作,以确保代码不会损坏任何数据并继续正常运行。通常不可能优雅地处理OutOfMemoryException
(并且在任何情况下保护new
的所有使用都是不切实际的(,但您当然可以捕获SocketException
,这可能由构造函数抛出。如果抛出该异常,则应立即放弃创建和使用TcpClient
的尝试,并向用户报告错误,以便他们可以尝试纠正阻止套接字创建的任何问题。 - 如果您的服务器预计会向您发送数据,而您没有收到数据,那么关闭连接并重试不太可能改善这种情况。这只会在服务器上造成额外的负载,使其更有可能无法响应。同样,一遍又一遍地发送相同的数据。您应该请求一次,等待服务器响应的时间尽可能长,如果在所需时间内没有收到响应,请向用户报告错误并让他们决定下一步该怎么做。
请注意,在这种情况下,您可以使用ReceiveTimeout
属性,因为如果您没有及时收到响应,您将要做的就是放弃连接,这很好。
很简单:
client.Close();
client = new TcpClient();
client.Connect(host, port);