2013-10-28 72 views
0

我使用這個實現返回NTP時間,在C#中的DateTime對象: https://stackoverflow.com/a/12150289/559988NTP UDP套接字接收任何數據,因此方法從不返回

但是因爲這是部署在軟件上多臺計算機在網絡上我不無法控制,問題就在於有時NTP有時會在這些網絡上被阻止。因此,當調用該方法時,它永遠不會返回,因爲它永遠不會獲取任何數據。

我試圖執行超時如下:

IAsyncResult result = socket.BeginConnect(ipEndPoint, null, null); 
Boolean success = result.AsyncWaitHandle.WaitOne(15000,true); 
if (!success) 
{ 
    socket.Close(); 
    throw new ApplicationException("Failed to connect to NTP server within 15 seconds"); 
} 

但超時不起作用,因爲該方法不返回。

有誰知道我可以如何實現一個套接字的超時,以便我至少可以故障轉移到另一種檢查NTP時間的方法?

感謝

編輯:我想弄清楚,如果沒有網絡連接(即您禁用適配器。)它沒有馬上就好了。這是一個網絡問題,一些網絡阻塞NTP協議(我認爲)會導致套接字打開,但掛在任一連接上或等待接收數據。

回答

2

我相信你實現的超時不起作用,因爲該方法總是立即返回。

UDP協議是無連接的。當您在UDP套接字上撥打Connect()時,並沒有真正發生,您只需設置一個默認端點,這樣您就不會在每個Send()呼叫中重複自己。

即使遠程主機無法訪問,Send()調用也會很快返回。在這種情況下,數據將會丟失,這就是UDP的工作原理。

底線: 您需要實現對Receive()叫了暫停:在BeginReceive方法「一個無效的參數提供」:

var result = socket.BeginReceive(ntpData, 0, ntpData.Length, SocketFlags.None, null, null); 
var success = result.AsyncWaitHandle.WaitOne(15000); 
if (!success) 
{ 
    socket.Close(); 
    throw new ApplicationException("Failed to connect to NTP server within 15 seconds"); 
} 
+0

這樣做,讓我一個例外。你能發佈一個完整的例子嗎? **大膽**編輯:**大膽**糟糕忘了做一些初始化;這似乎是訣竅! – cvocvo