异步读取期间TcpClient断开连接
本文关键字:断开 连接 TcpClient 读取 异步 | 更新日期: 2023-09-27 18:00:15
我有几个关于完成tcp连接的问题。
-
一个客户端使用Tcp连接到我的服务器,在接受了带有
listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);
的客户端之后,我开始使用networkStream.BeginRead(....)
进行读取
当我等待消息时客户端断开连接会发生什么?(例如,它失去电源、互联网等)
我如何知道它何时发生 -
如果在成功阅读后,我做了一些事情,然后调用
networkStream.Close(); client.Close();
,客户端会看到什么?如何"优雅地"终止连接? -
如果我正在等待读取(使用BeginRead),然后(在不同的线程上)关闭同一个流,会发生什么?
编辑添加:我确实在客户端和服务器之间有一条乒乓消息。够了吗?如果我没有收到ping,是否终止我的NetworkStream?肯定还有更好的东西。
1-如果客户端因电缆拔出而断开连接,则直到下一次对插槽进行读取或写入时才知道。还要注意tcpClient.Connected属性值不可靠,它的值取决于上次通信;因此,如果最后一次通信成功,那么它的值是真的,否则它就是假的。要了解更多信息,请查看此项。
2-如果关闭网络流和客户端,这就是客户端的正常终止。
3-我不知道,测试一下。
如果你意识到由于电缆拔出或其他原因导致连接丢失,那么为了获得适当的IsConnected值,你必须意识到在对tcp的读取或写入过程中丢失的连接,所以你需要通过在tcpclient的操作周围封装一个try-catch来访问tcpclient成员。。。。
使用此IsConnected属性检查tcpClient是否已连接:
public static bool IsConnected
{
get
{
try
{
//return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected;
if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected)
{
/* As the documentation:
* When passing SelectMode.SelectRead as a parameter to the Poll method it will return
* -either- true if Socket.Listen(Int32) has been called and a connection is pending;
* -or- true if data is available for reading;
* -or- true if the connection has been closed, reset, or terminated;
* otherwise, returns false
*/
// Detect if client disconnected
if (_tcpClient.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
{
// Client disconnected
return false;
}
else
{
return true;
}
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
当我等待消息时客户端断开连接会发生什么?(例如,它失去了电源、互联网等)我怎么知道它是什么时候发生的?
由于不同的断开原因,会发生不同的事情。
当您从socket.EndRead
接收到0个字节时,检测到正常断开连接。其他停机将导致EndRead
或Send
的SocketException
如果在成功阅读后,我做了一些事情,然后调用networkStream.Close();客户Close();客户会看到什么?如何"优雅地"终止连接?
Close会做得很优雅。
如果我正在等待读取(使用BeginRead),然后(在不同的线程上)关闭同一个流,会发生什么?
你会得到一个例外。ObjectDisposedException
(如果处置客户端)或IOException
public class Example
{
static NetworkStream stream;
static TcpClient client;
public static void Main(String[] args)
String message = String.Empty;
//TCP connection
Recon: Console.WriteLine("Connecting...");
Int32 port = 3333;
try
{
client = new TcpClient("ip.ip.ip.ip", port); //Try to connect
}
catch
{
Console.WriteLine("Problem while connecting!");
Thread.Sleep(10000); //Waiting 10s before reconnect
goto Recon;
}
Console.WriteLine("Connection established!'n");
stream = client.GetStream();
while (true)
{
//Buffer
byte[] received_bytes = new Byte[1024];
message = "";
Console.WriteLine("Waiting to receive message...'n");
Int32 bytes = stream.Read(received_bytes, 0, received_bytes.Length);
message = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(received_bytes, 0, bytes);
if (bytes == 0) //If connection abort while reading
{
Console.WriteLine("Connection failed!");
//Recconecting
goto Recon;
}
Console.WriteLine("Received message: " + message);
}
}
}