2009-06-11 71 views
3

我有一個簡單的頑劣服務器(用Groovy寫)的Java/Groovy的插座寫超時

ServerSocket ss = new ServerSocket(8889); 
Socket s = ss.accept() 
Thread.sleep(1000000) 

而且我希望有超時誰客戶端(因爲服務器沒有消耗它的輸入)

Socket s = new Socket("192.168.0.106", 8889) 
s.setSoTimeout(100); 
s.getOutputStream.write(new byte[1000000]); 

但是,此客戶端永遠阻止。我如何讓客戶端超時?

謝謝!

回答

3

你可以在它自己的線程中產生客戶端,然後旋轉鎖定/等待(超時時間長)來返回。如果套接字成功,則可能使用未來對象獲取返回值。

我確實相信Socket的SO_TIMEOUT設置隻影響從套接字讀取(..)調用,而不是寫入。

您可能會嘗試使用SocketChannel(而不是Stream)併產生另一個線程,該線程也具有該Channel的句柄。另一個線程可以在阻塞某個超時之後異步關閉該通道。

1

套接字超時位於TCP層,而不是應用程序層。源機器TCP正在緩衝要發送的數據,並且目標機器網絡堆棧正在確認收到的數據,因此沒有超時。而且,不同的TCP/IP實現以不同的方式處理這些超時。看看tcpdump(或wireshark,如果你真的很不幸:),你需要的是應用級ACK,即你需要定義客戶端和服務器之間的協議。我無法對Java程序包發表評論(您可能想看看nio),但收到該ACK的超時時間通常會與poll/select一起處理。

0

沒有辦法獲得超時,但是如果寫入沒有完成,您總是可以產生一個關閉連接的線程。