我一直在爭取整個3天的一個問題我找不到任何解決方案,請幫助:)
我使用Visual Studio 2010和C#語言。如何在連接後測試TCPClient斷開的連接?
我有一個像服務器一樣工作的設備,它在非常不規則的時間段內發送一些數據(不可能定義任何讀取超時)。
我寫了一個TCP客戶端連接到該服務器並讀取數據。它工作正常,但是當網絡出現問題並且服務器變得不可用時(例如,當我從計算機中拔出網線時),應用程序需要大約10秒鐘才能「注意到」,並且沒有連接到服務器並拋出一個例外。 (我不知道爲什麼正好10秒?它在什麼地方被定義了?我可以改變它嗎?)
我想反應更快 - 比方說連接斷開一秒後。
谷歌搜索答案然而不提供任何工作解決方案。
測試代碼如下,我嘗試在2個線程上進行測試:一個是讀取數據,另一個是查找連接狀態,當它斷開時應該報警。它不適用於TCPClient和Socket類。我試圖用tcpClient.SendTimeout = 100;
和stream.WriteTimeout = 100;
讀取/寫入一些數據,但它似乎不起作用。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace TCPClient
{
class Program
{
static volatile bool _continue = true;
static TcpClient tcpClient;
static NetworkStream stream;
static void Main(string[] args)
{
try
{
//client thread - listen from server
Thread tcpListenThread = new Thread(TcpListenThread);
tcpListenThread.Start();
//connection checking thread
Thread keepAliveThread = new Thread(KeepAliveThread);
keepAliveThread.Start();
while (_continue)
{
if (Console.ReadLine() == "q")
{
_continue = false;
}
}
keepAliveThread.Join(2000);
if (keepAliveThread.IsAlive)
{
Console.WriteLine("Thread keepAlive has been aborted...");
keepAliveThread.Abort();
}
tcpListenThread.Join(2000);
if (tcpListenThread.IsAlive)
{
Console.WriteLine("Listen thread has been aborted...");
tcpListenThread.Abort();
}
}
catch (Exception ex)
{
Console.WriteLine("\n" + ex.Message);
}
Console.WriteLine("\nHit any key to quit...");
Console.Read();
}
private static void TcpListenThread()
{
string server = "172.20.30.40";
int port = 3000;
try
{
using (tcpClient = new TcpClient())
{
tcpClient.Connect(server, port);
if (tcpClient.Connected)
Console.WriteLine("Successfully connected to server");
using (stream = tcpClient.GetStream())
{
while (_continue)
{
Byte[] data = new Byte[1024];
Int32 bytes = stream.Read(data, 0, data.Length);
string responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
Console.WriteLine("Received: {0}, responseData);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Listen thread exception! " + ex.Message);
}
}
private static void KeepAliveThread()
{
while (_continue)
{
if (tcpClient != null)
{
try
{
//...what to put here to check or throw exception when server is not available??...
}
catch (Exception ex)
{
Console.WriteLine("Disconnected...");
}
}
Thread.Sleep(1000); //test for connection every 1000ms
}
}
}
}
編輯:
@卡斯滕的回答是:雖然它看起來很有希望,這種解決方案不工作...
我做了最簡單的測試應用程序:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace TCPClientTest
{
class Program
{
static void Main(string[] args)
{
try
{
string server = "172.20.30.40";
int port = 3000;
using (TcpClient tcpClient = new TcpClient())
{
tcpClient.Connect(server, port);
int i = 0;
while (true)
{
// This is how you can determine whether a socket is still connected.
bool blockingState = tcpClient.Client.Blocking;
try
{
byte[] tmp = new byte[1];
tcpClient.Client.Blocking = false;
tcpClient.Client.Send(tmp, 0, 0);
Console.WriteLine("Connected!");
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
Console.WriteLine("Still Connected, but the Send would block");
else
{
Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
}
}
finally
{
tcpClient.Client.Blocking = blockingState;
}
Console.WriteLine("Connected: {0} ({1})", tcpClient.Client.Connected, i++);
Thread.Sleep(1000);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Global exception: {0}", ex.Message);
}
}
}
}
結果顯示如下:
連接!
連接:真
加上我的訂單號每隔一秒。當我斷開網絡電纜時,開始打印需要8秒鐘:
Disonnected:error code 10054!
連接:假
so by 8 seconds我不知道連接丟失。看起來pinging是最好的選擇,但我會測試另一種解決方案。
可能的重複:[如何檢查(TCP)套接字是否(在C#中)(dis)連接?](http://stackoverflow.com/questions/515458/how-can-i-check-whether-a -tcp-socket-is-disconnected-in-c) – ladenedge
@ladenedge可能重複...除了這個有更多的示例代碼來幫助其他人以不同的方式學習。我知道你的評論已經過時了,但是當你這樣的人毫無用處並且不鼓勵那些效率不高的評論時,這令人沮喪。 – Euthyphro