在C#中帶連線超時功能的TcpClient類
阿新 • • 發佈:2019-01-02
關於TcpClient 類在C#中對於操作TCP connection是非常方便的,非常地好!
但是有一點就是,這個類對於CONNECT操作沒有設定超時!
系統預設的是60秒的超時,這明顯過於地長。
我們可以重新去用Thread的join這個帶引數的執行緒,來解決這個問題,下面的這個類就是但連線超時引數的TCPCliento類
the TcpClientWithTimeout.cs class:
using System;
using System.Net.Sockets;
using System.Threading;
/// <summary>
/// TcpClientWithTimeout 用來設定一個帶連線超時功能的類
/// 使用者可以設定毫秒級的等待超時時間 (1000=1second)
/// 例如:
/// TcpClient connection = new TcpClientWithTimeout('127.0.0.1',80,1000).Connect();
/// </summary>
public class TcpClientWithTimeout
{
protected string _hostname;
protected int _port;
protected int _timeout_milliseconds;
protected TcpClient connection;
protected bool connected;
protected Exception exception;
public TcpClientWithTimeout(string hostname,int port,int timeout_milliseconds)
{
_hostname = hostname;
_port = port;
_timeout_milliseconds = timeout_milliseconds;
}
public TcpClient Connect()
{
// kick off the thread that tries to connect
connected = false;
exception = null;
Thread thread = new Thread(new ThreadStart(BeginConnect));
thread.IsBackground = true; // 作為後臺執行緒處理
// 不會佔用機器太長的時間
thread.Start();
// 等待如下的時間
thread.Join(_timeout_milliseconds);
if (connected == true)
{
// 如果成功就返回TcpClient物件
thread.Abort();
return connection;
}
if (exception != null)
{
// 如果失敗就丟擲錯誤
thread.Abort();
throw exception;
}
else
{
// 同樣地丟擲錯誤
thread.Abort();
string message = string.Format("TcpClient connection to {0}:{1} timed out",
_hostname, _port);
throw new TimeoutException(message);
}
}
protected void BeginConnect()
{
try
{
connection = new TcpClient(_hostname, _port);
// 標記成功,返回呼叫者
connected = true;
}
catch (Exception ex)
{
// 標記失敗
exception = ex;
}
}
}
下面的這個例子就是如何利用5秒的超時,去連線一個網站傳送10位元組的資料,並且接收10位元組的資料。
// connect with a 5 second timeout on the connection
TcpClient connection = new TcpClientWithTimeout("www.google.com", 80, 5000).Connect();
NetworkStream stream = connection.GetStream();
// Send 10 bytes
byte[] to_send = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xa};
stream.Write(to_send, 0, to_send.Length);
// Receive 10 bytes
byte[] readbuf = new byte[10]; // you must allocate space first
stream.ReadTimeout = 10000; // 10 second timeout on the read
stream.Read(readbuf, 0, 10); // read
// Disconnect nicely
stream.Close(); // workaround for a .net bug: http://support.microsoft.com/kb/821625
connection.Close();