簡體   English   中英

異步讀取期間TcpClient斷開連接

[英]TcpClient disconnect during async read

我有一些關於完成tcp連接的問題。

  1. 在使用listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);接受客戶端后,客戶端使用Tcp連接到我的服務器listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null); ,我開始用networkStream.BeginRead(....)閱讀。
    當我等待消息時客戶端斷開連接會發生什么? (例如,它失去了電力,互聯網等)
    我怎么知道它什么時候發生?

  2. 如果成功讀取后,我會做一些事情,然后調用networkStream.Close(); client.Close(); networkStream.Close(); client.Close(); 客戶會看到什么? 如何“優雅地”終止連接?

  3. 如果我正在等待讀取(使用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個字節時,會檢測到正常斷開連接。 其他關閉將導致EndReadSend 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM