我們有一個socket應用程序,while循環的代碼片段如下。我們想要檢查的是,如果它傳遞了30秒而沒有更多的數據,那麼關閉套接字連接。在事件中,如果有些數據在,那麼我們重置計時器。我必須使用計時器或系統毫秒數定時器檢查套接字連接上的活動?
while ((readChar=readSocket.read()) != -1)
{
//processing.
}
我們有一個socket應用程序,while循環的代碼片段如下。我們想要檢查的是,如果它傳遞了30秒而沒有更多的數據,那麼關閉套接字連接。在事件中,如果有些數據在,那麼我們重置計時器。我必須使用計時器或系統毫秒數定時器檢查套接字連接上的活動?
while ((readChar=readSocket.read()) != -1)
{
//processing.
}
您可以配置套接字,以便在指定時間間隔內沒有收到數據時讀取操作超時。
public void setSoTimeout(int timeout) throws SocketException
啓用與指定的超時/禁用SO_TIMEOUT,以毫秒爲單位。如果將此選項設置爲非零超時,則與此Socket關聯的InputStream上的read()調用將僅阻塞這段時間。如果超時過期,則會引發java.net.SocketTimeoutException,但Socket仍然有效。該選項必須在進入阻止操作生效之前啓用。超時值必須大於0.超時值爲零將被解釋爲無限超時。
Parameters: timeout - the specified timeout, in milliseconds. Throws: SocketException - if there is an error in the underlying protocol, such as a TCP error. Since: JDK 1.1 See Also: getSoTimeout()
使用這種方法,你可以讀取數據,消耗它(但你的需要),然後再次從套接字讀取。如果您遇到超時異常,請關閉套接字。
socket.setSoTimeout(30 * 1000); // timeout after 30 seconds
try
{
while ((readChar=readSocket.read()) != -1) // block reading data ...
{
// processing ...
}
}
catch (SocketTimeoutException e) // we didn't get any data within 30 seconds ...
{
socket.close(); // ... close the socket
}
使用異步NIO操作。 如果你使用java6,異步操作很棘手,但是有很多網絡庫(Mina,Netty),儘管它們相當重。 如果您使用java7,則實現真正的異步網絡操作並且易於使用(nio2)。更容易的是使用https://github.com/rfqu/df4j的輕量級nio2庫。
現在使用socket.setSoTimeout的問題是,例如,如果我在套接字關閉30秒後立即設置了30秒。我所要求的是,只要數據保存進來就可以收到它。在該批次中的最後一個數據之後的那一刻,我想設置一個計時器,並檢查在這30秒內沒有更多的數據,然後只斷開插座? – user837306 2012-04-03 17:59:43
如果經過30秒並且沒有收到數據,SO_TIMEOUT將導致SocketTimeoutException異常 - (a)如果接收到數據*,則超時不會過期,並且(b)由您自行採取行動並且關閉插座。現在要澄清的是,你是否說過在開始時你想阻止無限期地等待數據到達 - 然後,一旦數據到達,等待30秒(萬一有更多的數據到達),然後關閉套接字?如果是這樣,那麼可以通過在上面的代碼中添加幾個檢查來確定我們是處於「初始」還是「數據接收後」狀態。 – 2012-04-03 22:38:25
確定最初我會建立連接,並使用分隔符ask#繼續閱讀字符。所以一旦我看到散列意味着我已經閱讀了一個完整的數據/行。此後,我需要在30秒內等待沒有更多的數據纔會關閉連接。希望我現在清楚。所以即使在開始時,如果連接30秒內沒有數據出現,我也不想無限期地阻止。 – user837306 2012-04-04 02:45:51