C#中, 對於Socket的請求,無論是同步還是異步,都沒有提供超時機制,SendTimeout,ReceiveTimeout均無用..
對於需要測試網絡是否正常連接的情況下,超時控制很是有用, 如果服務器不存在,或是客戶機網絡異常,, 在沒有設置超時的情況下,,Socket請求需要等40s-70s...終於在網上找到解決的辦法。
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,則認爲網絡連接超時..