簡體   English   中英

斷開TCPClient並在另一端看到它

[英]Disconnecting TCPClient and seeing that on the other side

我試圖斷開客戶端與服務器的連接,但服務器仍然將其視為已連接。 我無法找到解決方案,關閉,斷開和關閉所有不工作。

我與客戶端斷開連接並檢查服務器的一些代碼:

客戶:

  private void btnDisconnect_Click(object sender, EventArgs e)
    {
        connTemp.Client.Shutdown(SocketShutdown.Both);
        connTemp.Client.Disconnect(false);
        connTemp.GetStream().Close();
        connTemp.Close();
    }

服務器:

    while (client != null && client.Connected)
            {
                NetworkStream stream = client.GetStream();
                data = null;

                try
                {
                    if (stream.DataAvailable)
                    {
                        data = ReadStringFromClient(client, stream);
                        WriteToConsole("Received Command: " + data);
                    }
                } // So on and so on...

代碼中還有更多的寫入和讀取。

希望你們都能提供幫助。

更新:我甚至嘗試通過ref傳遞TCP客戶端,假設存在范圍問題和client.Connected即使在讀取后仍然為真。 出了什么問題?

第二次更新!!:

這是解決方案。 先查看並確定是否已連接。

  if (client.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] checkConn = new byte[1];
                        if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                        {
                            throw new IOException();
                        }
                    }

這是解決方案!!

  if (client.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] checkConn = new byte[1];
                    if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                    {
                        throw new IOException();
                    }
                }

MSDN文檔

Connected屬性從最后一個I / O操作開始獲取Client套接字的連接狀態。

當它返回false時,Client套接字從未連接,或者不再連接。 由於Connected屬性僅反映最近操作時的連接狀態,因此您應嘗試發送或接收消息以確定當前狀態。 消息發送失敗后,此屬性不再返回true。 請注意,此行為是設計使然。 您無法可靠地測試連接狀態,因為在測試和發送/接收之間的時間內,連接可能已丟失。 您的代碼應該假定套接字已連接,並正常處理失敗的傳輸。

我不確定NetworkStream類,但我認為它的行為類似於Socket類,因為它主要是一個包裝類。 通常,服務器不會意識到客戶端與套接字斷開連接,除非它在套接字上執行I / O操作(讀取或寫入)。 但是,當您在套接字上調用BeginRead時,在從套接字讀取數據之前不會調用回調,因此調用EndRead並獲取字節讀取返回結果為0(零)表示套接字已斷開連接。 如果您使用Read並獲得零字節讀取結果,我懷疑您可以檢查基礎Socket類上的Connected屬性,如果客戶端因為在套接字上執行了I / O操作而斷開連接,則它將為false。

這是一個普遍的TCP問題,請參閱:

對此的解決方法往往依賴於作為協議的一部分發送預期的數據量。 這就是HTTP 1.1使用Content-Length頭(對於整個實體)或使用分塊傳輸編碼(具有各種塊大小)所做的事情。

另一種方法是定期發送“NOOP”或類似命令(本質上只是確保通信仍然打開的消息)作為協議的一部分。

(您還可以向協議添加一個命令,客戶端可以將該命令發送到服務器以干凈地關閉連接,但不能獲取它並不意味着客戶端沒有斷開連接。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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