2017-07-05 106 views
1

我希望看到一個HTTP客戶端如何響應連接超時,即那裏的端口上監聽的服務器,但建立連接的過程是如此緩慢,客戶端放棄並返回一個連接超時。連接不應該被拒絕,它不應該被接受,然後在套接字超時之後。如何模擬本地端口上的網絡延遲?

到目前爲止,我已經嘗試通過重寫ServerSocket,想象我能寫出像這樣引入網絡延遲...

public SlowServerSocket extends ServerSocket { 
    // (This method doesn't actually exist). 
    @Override 
    public void processBytesPassedOnByOperatingSystem(byte[] bytes) { 
     Thread.sleep(delay); 
     // Client has already returned a connection timeout. 
     super.processBytesPassedOnByOperatingSystem(bytes); 
    } 
} 

...但我碰到一個死衚衕當我達到這個抽象層次時(它似乎隱藏在本地方法中)。我的假服務器接受連接,然後什麼也不做,導致套接字超時。

我也在網上尋找解決方案,我從JMeter庫中找到了SlowSocket,但它似乎在客戶端使用(我認爲我不能覆蓋客戶端所以它使用SlowSocket)。

有什麼建議嗎?

+0

注筆者:我發現這個答案,https://stackoverflow.com/questions/100841/artificially-create-a-connection-timeout-錯誤,這表明連接到不可路由的地址,如「10.255.255.1」。但是,我不確定它是最可靠的便攜式解決方案。 – Pig

+0

也許值得繼承'SecurityManager'並覆蓋'checkAccept()'方法,使它睡眠,然後調用System.setSecurityManager(overridenSecurityManager)。想法來自這裏:https://stackoverflow.com/questions/7800960/java-socket-listen-before-accept?rq=1 – Pig

回答

0

我想看看HTTP客戶端如何反應連接超時,即有一個服務器偵聽端口,但建立連接的過程非常慢,客戶端放棄並返回連接超時。

您的需求體現在矛盾的。當對等主機完全沒有響應時,通常會因爲防火牆而發生連接超時。它與服務器應用程序緩慢無關。服務器不'建立連接':TCP堆棧。

連接不應該被拒絕

這不會是如果有一個聽的過程中,除了下面。

它不應該被接受,然後是套接字超時。

這正是你所編寫的代碼會產生。

然而當且僅當服務器平臺而不是Windows,還有另一種方式來產生一個連接超時:讓backlog隊列填滿。爲了達到這個目的,讓服務器執行所有正常的套接字設置步驟,但根本不會調用accept(),並讓客戶端執行大量的連接嘗試。但是如果服務器平臺是Windows,這將產生連接拒絕。

+0

所以連接被拒絕時,「TCP堆棧」(對不起,我有一點知識此區域)無法連接到目標端口,因爲沒有進程在該端口上偵聽?當TCP數據包甚至沒有到達目的地/連接超時時,連接超時? – Pig

+0

@Pig如果沒有監聽進程,或者積壓隊列已滿並且服務器平臺是Windows,則拒絕連接。我已經說過了。連接超時,如果對方沒有及時響應,或根本沒有響應。我已經說過了。 – EJP

-1

我也在網上尋找解決方案,我碰到了JMeter庫中的SlowSocket,但它似乎在客戶端使用(我認爲我不能重寫客戶端使它使用SlowSocket)。

可以使用Sniffy模擬網絡延遲 - 它與Java的TCP協議棧無縫集成,並不需要從應用程序方面的任何變化。見documentation on emulating network issues

可在 demo.sniffy.io

在線演示 - 在右下角點擊小工具,去「網絡連接」選項卡並設置延遲說1000毫秒en.wikipedia.org。刷新瀏覽器頁面,您會看到加載該頁面需要1秒多的時間。 javaagent integration也適用於非Web應用程序。

enter image description here

免責聲明:我的Sniffy

+0

但它模擬一個慢連接階段?如果是這樣,怎麼樣? – EJP

+0

TCP中的連接階段基本上爲第一個數據包增加了一個往返行程(SYN和SYN-ACK數據包不帶應用程序數據,僅與ACK數據包一起發送)。在Java應用程序中無法訪問IP數據包,因此Sniffy使用一些啓發式方法來添加延遲,如下所述:http://sniffy.io/docs/latest/#_emulating_network_issues;將指定的延遲添加到客戶端的Socket.connect()方法 – bedrin

+0

這不是要求的。他希望看到他的*現有*客戶端如何對連接超時做出反應,並且您所做的任何事情都不會導致連接超時。 – EJP