C 中設定Socket連線請求的超時
阿新 • • 發佈:2018-12-20
C#中, 對於Socket的請求,無論是同步還是非同步,都沒有提供超時機制,SendTimeout,ReceiveTimeout均無用..
對於需要測試網路是否正常連線的情況下,,超時控制很是有用, 如果伺服器不存在,或是客戶機網路異常,, 在沒有設定超時的情況下,,Socket請求
需要等很久...
於是找呀找,,終於在網上找到解決的辦法, 程式碼如下...
[csharp] view plain copy print?- <code class="language-csharp"> privatereadonly ManualResetEvent TimeoutObject = new
- /// <summary>
- /// Socket連線請求
- /// </summary>
- ///<param name="remoteEndPoint">網路端點</param>
- ///<param name="timeoutMSec">超時時間</param>
- publicvoid Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
- {
- TimeoutObject.Reset();
- var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- socket.BeginConnect(remoteEndPoint, CallBackMethod, socket);
- //阻塞當前執行緒
- if (TimeoutObject.WaitOne(timeoutMSec,
- {
- //MessageBox.Show("網路正常");
- }
- else
- {
- //MessageBox.Show("連線超時");
- }
- }
- //--非同步回撥方法
- privatevoid CallBackMethod(IAsyncResult asyncresult)
- {
- //使阻塞的執行緒繼續
- TimeoutObject.Set();
- }</code>
private readonly ManualResetEvent TimeoutObject = new ManualResetEvent(false); /// <summary> /// Socket連線請求 /// </summary> ///<param name="remoteEndPoint">網路端點</param> ///<param name="timeoutMSec">超時時間</param> public void Connect(IPEndPoint remoteEndPoint, int timeoutMSec) { TimeoutObject.Reset(); var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.BeginConnect(remoteEndPoint, CallBackMethod, socket); //阻塞當前執行緒 if (TimeoutObject.WaitOne(timeoutMSec, false)) { //MessageBox.Show("網路正常"); } else { //MessageBox.Show("連線超時"); } } //--非同步回撥方法 private void CallBackMethod(IAsyncResult asyncresult) { //使阻塞的執行緒繼續 TimeoutObject.Set(); }
程式碼雖然簡單,不過其思路還是不錯的,大概說一下其原理:
重點就是TimeoutObject.WaitOne與Socket的BeginConnect非同步請求的回撥函式CallBackMethod.!
首先利用TimeoutObject.WaitOne阻塞當前執行緒,並設定等待時間,,如果在等待的時間內仍然無訊號,則判斷為連線超時,
在網路正常連線的情況下,通過Socket的BeginConnect非同步請求,伺服器正常回應,則會呼叫CallBackMethod回撥函式,關鍵就在這裡了,我們在CallBackMethod函式中,給予TimeoutObject訊號,TimeoutObject在指定時間timeoutMSec內收到訊號,WaitOne返回True,則認為網路連線正常..
如果網路異常,,CallBackMethod函式得不到呼叫,TimeoutObject則一直處於等待狀態,超過指定的時間.,WaitOne不再繼續等待,直接返回False,則認為網路連線超時..