用TcpClient作通訊的時候,常常發現網絡鏈接不通的時候,代碼就卡死在那裏,TcpClient居然沒有超時的設定 淚奔啊 看來微軟不是把全部工具準備得妥穩當當的啊網絡
沒辦法 如今用線程來包裝一下這個類 ,勉強可以使用。socket
先上第一個類:這是網上的一種解決方案。async
class TimeOutSocket { private static bool IsConnectionSuccessful = false; private static Exception socketexception; private static ManualResetEvent TimeoutObject = new ManualResetEvent(false); public static TcpClient TryConnect(IPEndPoint remoteEndPoint, int timeoutMiliSecond) { TimeoutObject.Reset(); socketexception = null; string serverip = Convert.ToString(remoteEndPoint.Address); int serverport = remoteEndPoint.Port; TcpClient tcpclient = new TcpClient(); tcpclient.BeginConnect(serverip, serverport, new AsyncCallback(CallBackMethod), tcpclient); if (TimeoutObject.WaitOne(timeoutMiliSecond, false)) { if (IsConnectionSuccessful) { return tcpclient; } else { throw socketexception; } } else { tcpclient.Close(); throw new TimeoutException("TimeOut Exception"); } } private static void CallBackMethod(IAsyncResult asyncresult) { try { IsConnectionSuccessful = false; TcpClient tcpclient = asyncresult.AsyncState as TcpClient; if (tcpclient.Client != null) { tcpclient.EndConnect(asyncresult); IsConnectionSuccessful = true; } } catch (Exception ex) { IsConnectionSuccessful = false; socketexception = ex; } finally { TimeoutObject.Set(); } } }
插入第二種,本身實現的超時處理代碼tcp
static void Main(string[] args) { CancellationTokenSource c = new CancellationTokenSource(); CancellationToken token = c.Token; Task task = new Task(() => { TcpClient client = new TcpClient(AddressFamily.InterNetwork); client.SendTimeout = 6000; client.ReceiveTimeout = 6000; client.Connect(IPAddress.Parse("192.168.0.49"), int.Parse("60000")); if (client.Connected) { byte[] data = System.Text.Encoding.UTF8.GetBytes("AAAAABDEEKRJOWEQRIO@#$(*#@&%"); byte[] buffer = new byte[32]; string responseData = string.Empty; using (NetworkStream stream = client.GetStream()) { Encoding encode = System.Text.Encoding.GetEncoding("utf-8"); StreamReader Reader = new StreamReader(stream, encode); Console.WriteLine("\nResponse stream received"); Char[] read = new Char[16]; int count = 0; do { count = Reader.Read(read, 0, 16); String str = new String(read, 0, count); Console.Write(str); } while (count > 0); Reader.Close(); } } while (true) { if (token.IsCancellationRequested) { throw new OperationCanceledException(); } } }, token); task.Start(); if (task.Wait(3000, token)) { } else { c.Cancel(); Console.WriteLine("任務已經取消"); } }
OK,先寫這麼多吧工具