[英]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.