背景/平臺:TcpClient的持續發送了一段時間,即使沒有連接
.NET 4/C#
我有一個C#TcpClient
連接到以太網一個嵌入式設備。 我正在使用兩個定時器 - 一個用於將接收到的數據存儲在本地Queue<MyMessage>
中,另一個用於通過TCP將另一個Queue<MyMessage>
的數據發送到嵌入式設備。這兩種方法每個都運行200 ms
併發送/讀取他們必須發送/讀取的任何內容。
還有一個定時器發送保持活動數據包every second
(目前僅用於調試目的)。
情景/問題
建立連接後,嵌入式設備開始一些數據發送給我的TcpClient
。這按預期工作(參見下面的消息日誌)。但是,我關閉該設備(所以它根本不工作)。這意味着它甚至無法正確關閉TCP。但沒關係。我想測試一下如果像這樣發生在真實情況下會發生什麼。
但是,即使服務器(設備)不再在線,TcpClient仍會繼續發送數據。
下面是發送(使用NetworkStream.Write
)的代碼:發送另一個45-50秒,不斷去,最後它打破
while (messagesToSend.Count > 0)
{
MyMessage msg = messagesToSend.Dequeue();
clientStream.Write(msg.Data, 0, msg.Data.Length);
Debug.WriteLine(DateTime.Now.ToString() + " Sent: " + msg.MessageID);
}
。 這些是TcpClient的和的NetworkStream
client.LingerState = new LingerOption(true, 0);
client.NoDelay = true;
client.SendTimeout = 3000;
clientStream.WriteTimeout = 3000;
設置在這裏的選項是調試輸出:
16:32:02 Connecting
16:32:02 Authorizing
16:32:02 Sent: 255
16:32:02 Sent: 0
16:32:02 Authorized
16:32:02 Connected
16:32:02 Received: 255
16:32:02 Received: 226
...
... some regular communication here
...
16:32:06 Received: 251
16:32:06 Sent: 0
16:32:07 Received: 251
16:32:07 Sent: 0 // At this point I have turned off the device
16:32:08 Sent: 0
16:32:09 Sent: 0
...
... every second the same message
...
16:32:54 Sent: 0
16:32:55 Sent: 0
16:32:56 Sent: 0
16:32:57 Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
16:32:57 CommunicationError
它爲什麼花了這麼長時間的連接來實現,它被關閉?如果主機沒有響應,NetworkStream.Write
不應該立即失敗?
如何到檢測到設備的電源被切斷,連接不再有效?
所以基本上,知道連接是否仍然有效的唯一方法是服務器(本例中的設備)每XY秒發送一次自定義協議消息,然後如果我沒有收到它一個XY(或多一點)秒我知道出了什麼問題?我知道,當連接失敗時,Read操作將返回0(因爲接收到0字節),但它似乎只能在Read上工作,而不能在Write上工作。 –
不是。數據包仍然可以在這裏和這裏之間緩衝。唯一可以衡量的是rtt(往返時間)。如果你真的想要構建你正在描述的東西,那麼切換到不執行重發的udp(等等)。 – sisve