[英]TcpClient disconnect during async read
我有一些關於完成tcp連接的問題。
在使用listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);
接受客戶端后,客戶端使用Tcp連接到我的服務器listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);
,我開始用networkStream.BeginRead(....)
閱讀。
當我等待消息時客戶端斷開連接會發生什么? (例如,它失去了電力,互聯網等)
我怎么知道它什么時候發生?
如果成功讀取后,我會做一些事情,然后調用networkStream.Close(); client.Close();
networkStream.Close(); client.Close();
客戶會看到什么? 如何“優雅地”終止連接?
如果我正在等待讀取(使用BeginRead),然后(在不同的線程上)關閉相同的流會發生什么?
編輯添加:我確實在客戶端和服務器之間發生了乒乓消息。 夠了嗎? 如果我沒有收到ping,請終止我的NetworkStream? 肯定有一些更好的東西。
1-如果客戶端因拔下電纜而斷開連接,則在下次讀取或寫入插座之前,您將無法知道。 還要注意tcpClient.Connected屬性值不可靠,它的值取決於上次通信; 因此,如果最后一次通信成功,則它的值為true,否則為false。 有關檢查的更多信息,請查看此信息
2-如果關閉網絡流和客戶端,則這是客戶端的正常終止。
3-我不知道,給它一個測試。
如果您因為拔掉電纜而導致連接丟失,那么為了獲得適當的IsConnected值,您必須了解在讀取或寫入tcp期間丟失的連接,因此您需要通過嘗試來訪問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(); client.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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.