日期:2014-05-18 浏览次数:20927 次
using System; using System.Net.Sockets; using System.Threading; /// <summary> /// TcpClientWithTimeout is used to open a TcpClient connection, with a /// user definable connection timeout in milliseconds (1000=1second) /// Use it like this: /// 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; // So that a failed connection attempt // wont prevent the process from terminating while it does the long timeout thread.Start(); // wait for either the timeout or the thread to finish thread.Join(_timeout_milliseconds); if (connected == true) { // it succeeded, so return the connection thread.Abort(); return connection; } if (exception != null) { // it crashed, so return the exception to the caller thread.Abort(); throw exception; } else { // if it gets here, it timed out, so abort the thread and throw an exception 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); // record that it succeeded, for the main thread to return to the caller connected = true; } catch (Exception ex) { // record the exception for the main thread to re-throw back to the calling code exception = ex; } } } And here's a little example of how to use this to open a connection, send 10 bytes, and receive 10 bytes: // 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();