1. 程式人生 > >C#中設定Socket連線請求的超時

C#中設定Socket連線請求的超時

C#中, 對於Socket的請求,無論是同步還是非同步,都沒有提供超時機制,SendTimeout,ReceiveTimeout均無用..

對於需要測試網路是否正常連線的情況下,,超時控制很是有用,  如果伺服器不存在,或是客戶機網路異常,, 在沒有設定超時的情況下,,Socket請求

需要等很久...

於是找呀找,,終於在網上找到解決的辦法,  程式碼如下...

 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,則認為網路連線超時..