2011-07-11 150 views
2

如果通過Socket連接的客戶端具有較差的延遲,會發生什麼情況? 假設我從TCP服務器調用socket.read(),並且客戶端在網絡管道上寫入了一些內容,但他的連接持續了1或2分鐘。會發生什麼 ? read會失敗嗎?還是會等待?我不確定是否有可能,但我在FICS服務器上玩在線國際象棋,有時它似乎從我的角度來看(我只是這個國際象棋服務器的用戶)。讀取期間Java套接字超時

我在問這個,因爲我在網絡遊戲上工作,我想以這種或那種方式處理這種情況。但首先我需要知道:

  • 它可以發生
  • 可以檢測

感謝

回答

2

我建議不要僅僅依靠設置SO_TIMEOUT變量,而是在您的客戶端和服務器之間添加應用程序級別的心跳。如果客戶端或服務器在指定時間內沒有收到心跳消息(例如在心跳頻率的兩倍以內),則應斷開連接,並在客戶端嘗試重新連接。

使用心跳機制還允許您通過監視每端接收心跳消息的延遲來測量延遲。

+0

這就是我要做的 – Joel

+0

我只是在想...這太糟糕了,它並沒有包含在普通的TCP – Joel

+0

是的,這令人沮喪,但我可以理解爲什麼它不是協議的一部分,因爲不同的應用程序有不同的要求。 – Adamski

1

read() - 方法將發生阻塞。但有setSoTimeout()-method可用於設置可處理的超時。

+0

我知道這個選項,但它如何幫助區分滯後與缺少活動? – Joel

+0

我不認爲你可以。您可以使用超時緩衝延遲,如果沒有響應,則需要假定客戶端沒有任何東西進來。 –

0

其實,使用setSoTimeout()可能有點誤導。當您以這種方式使用它時:

Socket sock = new Socket(host, port); 
sock.setSoTimeout(3000); // 3 seconds timeout 

構造函數在沒有設置超時的情況下啓動connect()。而不是預期的3秒超時,你會得到默認值。要獲得期望的超時時間,您可以按照以下方法進行:

SocketAddress sockaddr = new InetSocketAddress(host, port); 
Socket sock = new Socket(); 
sock.connect(sockaddr, 3000); // 3 seconds timeout