java socket參數詳解:BackLogjava
輸入鏈接指示(對鏈接的請求)的最大隊列長度被設置爲 backlog 參數。若是隊列滿時收到鏈接指示,則拒絕該鏈接。
注意:
1. backlog參數必須是大於 0 的正值。若是傳遞的值等於或小於 0,則假定爲默認值。
2. 通過測試這個隊列是按照FIFO(先進先出)的原則。
3. 若是將accept這個函數放在一個循環體中時,backlog參數也不會有什麼做用。或者簡單的講運行ServerSocket的這個線程會阻塞時,不管是在accept,仍是在read處阻塞,這個backlog參數才生效。
建一個ServerSocket實例,綁定到端口10000,backlog設置爲2apache
Java代碼 服務器
package socket; import java.io.*; import java.net.*; import org.apache.log4j.Logger; public class Test_backlog { private static Logger logger = Logger.getLogger(Test_backlog.class); public static void main(String[] args) throws Exception { BufferedReader in = null; PrintWriter out = null; int backlog = 2; ServerSocket serversocket = new ServerSocket(10000, backlog); while (true) { logger.debug("啓動服務端......"); int i; Socket socket = serversocket.accept(); logger.debug("有客戶端連上服務端, 客戶端信息以下:" + socket.getInetAddress() + " : " + socket.getPort() + "."); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); do { char[] c = new char[1024]; i = in.read(c); logger.debug("服務端收到信息: " + new String(c, 0, i)); } while (i == -1); out.close(); in.close(); socket.close(); logger.debug("關閉服務端......"); } } }
服務端日誌:socket
Python代碼 函數
0 [main] DEBUG socket.Test_backlog - 啓動服務端...... 3871 [main] DEBUG socket.Test_backlog - 有客戶端連上服務端, 客戶端信息以下:/127.0.0.1 : 4176. 18888 [main] DEBUG socket.Test_backlog - 服務端收到信息: 發送完信息我就斷掉。 18888 [main] DEBUG socket.Test_backlog - 關閉服務端...... 18889 [main] DEBUG socket.Test_backlog - 啓動服務端...... 18890 [main] DEBUG socket.Test_backlog - 有客戶端連上服務端, 客戶端信息以下:/127.0.0.1 : 4177. 45316 [main] DEBUG socket.Test_backlog - 服務端收到信息: 我是第二個客戶端,發完後我也斷掉。 45316 [main] DEBUG socket.Test_backlog - 關閉服務端...... 45316 [main] DEBUG socket.Test_backlog - 啓動服務端...... 45317 [main] DEBUG socket.Test_backlog - 有客戶端連上服務端, 客戶端信息以下:/127.0.0.1 : 4178. 52501 [main] DEBUG socket.Test_backlog - 服務端收到信息: 最後一個拉。 52501 [main] DEBUG socket.Test_backlog - 關閉服務端......
使用TCP工具鏈接這個服務端
1. 當第一個客戶端鏈接時,服務端打出以下信息:
6629 [main] DEBUG socket.Test_backlog - 有客戶端連上服務端, 客戶端信息以下:/127.0.0.1 : 4110.
2. 當第二個客戶端鏈接時,服務端沒有打出任何東東。由於這時客戶端若是雖然顯示成功了,可是被阻在鏈接隊列中。
3. 當第三個客戶端鏈接時,狀況與2相同。
4. 當第四個客戶端鏈接時,鏈接不上並報錯。由於backlog參數設置成2,隊列中只有阻塞兩個。
總結:
管理客戶鏈接請求的任務是由操做系統來完成的。操做系統把這些鏈接請求存儲在一個先進先出的隊列中。許多操做系統限定了隊列的最大長度,通常爲50。當隊列中的鏈接請求達到了隊列的最大容量時,服務器進程所在的主機會拒絕新的鏈接請求。只有當服務器進程經過ServerSocket的accept()方法從隊列中取出鏈接請求,使隊列騰出空位時,隊列才能繼續加入新的鏈接請求。
對於客戶進程,若是它發出的鏈接請求被加入到服務器的隊列中,就意味着客戶與服務器的鏈接創建成功,客戶進程從Socket構造方法中正常返回。若是客戶進程發出的鏈接請求被服務器拒絕,Socket構造方法就會拋出ConnectionException。工具