我有一個打開只讀 TCP 流套接字的應用程式。我已經設定了 KeepAlive 以確保每秒發送一條訊息以檢查連接是否仍然正常。Wireshark 顯示 KeepAlive 訊息被另一臺計算機發送并確認。我的應用程式在 Windows 上運行。
與網路/互聯網的其余部分相比,我打開套接字的遠程機器位于單獨的 LAN 配接器上。

有兩種情況似乎以不同的方式作出反應,我想知道為什么。
- 我已連接到互聯網。TCP Keep-Alive 每秒都在增強。我從機器上拔下 LAN 電纜。最后一個 TCP Keep-Alive 不是 ACKd,因此
Socket.Connected是false,正如預期的那樣。 - 我沒有連接到互聯網。TCP Keep-Alive 每秒都在增強。我從機器上拔下 LAN 電纜。根本沒有TCP Keep-Alive 包被發送到遠程機器,因此
Socket.Connected仍然是true.
當套接字發送 TCP Keep-Alive 包時,我是否錯過了一個重要的概念?例如,如果您根本沒有網路連接,請不要發送?如果是這樣,我如何確保套接字不再存在Connected?
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.SetupKeepAlive();
_socket.Blocking = false;
public static void SetupKeepAlive(this Socket socket, uint interval = 1000U)
{
if (socket is null)
{
throw new ArgumentNullException(nameof(socket));
}
// Get the size of the uint to use to back the byte array
var size = Marshal.SizeOf(0U);
// Create the byte array
var keepAlive = new byte[size * 3];
// Pack the byte array:
// Turn keep-alive on
Buffer.BlockCopy(BitConverter.GetBytes(1U), 0, keepAlive, 0, size);
// Set amount of time without activity before sending a keep-alive
Buffer.BlockCopy(BitConverter.GetBytes(interval), 0, keepAlive, size, size);
// Set keep-alive interval
Buffer.BlockCopy(BitConverter.GetBytes(interval), 0, keepAlive, size * 2, size);
// Set the keep-alive settings on the underlying Socket
_ = socket.IOControl(IOControlCode.KeepAliveValues, keepAlive, null);
}
uj5u.com熱心網友回復:
套接字不知道 Internet 連接的可用性,但它知道網路設備狀態。它只是一個非常低級的 TCP 單元。
它只能發送和接收一些不能診斷網路設備背后的網路的東西。我沒有閱讀 RFC,但您所描述的行為是預期的。
當 TCP 連接啟動時,Keep-alive 將定期發送。
因此 Socket.Connected 仍然是真的
看起來像一個已知的 TCP 隊頭問題。套接字正在等待回應,直到超時發生被關閉。
想象一下設定:您處于糟糕的連接環境中,某些主機正在丟失資料包或掛起幾秒鐘。然后,如果 Socket 僅在未收到保持活動的 ping 時才在 timout 之前關閉連接,您將獲得關閉的連接。Keep-alive 旨在使連接壽命更長而不是更短。
還有一個提示:
var keepAlive = new byte[12];
var values = MemoryMarshal.Cast<byte, int>(ref keepAlive);
values[0] = 1;
values[1] = interval; // make it int
values[2] = interval;
// the values were written directly to byte[] array
看起來您使用了錯誤的數字大小。陣列大小預期為 12 位元組 (3x4),而不是 24 位元組 (3x8)。可能您將 C long用作 C# long。但是,C long是int在C#中。C#long是 C long long。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/371988.html
