熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java Socket重要參數講解

2013-11-23 19:16:44  來源: Java核心技術 

  Java Socket的api可能很多人會用但是Java Socket的參數可能很多人都不知道用來干嘛的甚至都不知道有這些參數

  backlog

  用於ServerSocket配置ServerSocket的最大客戶端等待隊列等待隊列的意思先看下面代碼

  public class Main { public static void main(String[] args) throws Exception { int port = int backlog = ServerSocket serverSocket = new ServerSocket(port backlog)Socket clientSock = serverSocketaccept()Systemoutprintln(revcive from + clientSockgetPort())while (true) { byte buf[] = new byte[]int len = clientSockgetInputStream()read(buf)Systemoutprintln(new String(buf len))}這段測試代碼在第一次處理一個客戶端時就不會處理第二個客戶端所以除了第一個客戶端其他客戶端就是等待隊列了所以這個服務器最多可以同時連接個客戶端其中個等待隊列大家可以telnet localhost 測試下

  這個參數設置為表示無限制默認是個最大等待隊列如果設置無限制那麼你要小心了如果你服務器無法處理那麼多連接那麼當很多客戶端連到你的服務器時每一個TCP連接都會占用服務器的內存最後會讓服務器崩潰的

  另外就算你設置了backlog為如果你的代碼中是一直Socket clientSock = serverSocketaccept()假設我們的機器最多可以同時處理個請求總共有個線程在運行然後你把在個線程的線程池處理clientSock不能處理的clientSock就排隊最後clientSock越來越多也意味著TCP連接越來越多也意味著我們的服務器的內存使用越來越高(客戶端連接進程肯定會發送數據過來數據會保存到服務器端的TCP接收緩存區)最後服務器就宕機了所以如果你不能處理那麼多請求請不要循環無限制地調用serverSocketaccept()否則backlog也無法生效如果真的請求過多只會讓你的服務器宕機(相信很多人都是這麼寫要注意點)

  TcpNoDelay

  禁用納格算法將數據立即發送出去納格算法是以減少封包傳送量來增進TCP/IP網絡的效能當我們調用下面代碼

  Socket socket = new Socket()nnect(new InetSocketAddress(host ))InputStream in = socketgetInputStream()OutputStream out = socketgetOutputStream()String head = hello String body = world\r\noutwrite(headgetBytes())outwrite(bodygetBytes())我們發送了hello當hello沒有收到ack確認(TCP是可靠連接發送的每一個數據都要收到對方的一個ack確認否則就要重發)的時候根據納格算法world不會立馬發送會等待要麼等到ack確認(最多等ms對方會發過來的)要麼等到TCP緩沖區內容>=MSS很明顯這裡沒有機會我們寫了world後再也沒有寫數據了所以只能等到hello的ack我們才會發送world除非我們禁用納格算法數據就會立即發送了

  SoLinger

  當我們調用socketclose()返回時socket已經write的數據未必已經發送到對方了例如

  Socket socket = new Socket()nnect(new InetSocketAddress(host ))InputStream in = socketgetInputStream()OutputStream out = socketgetOutputStream()String head = hello String body = world\r\noutwrite(headgetBytes())outwrite(bodygetBytes())socketclose()

  這裡調用了socketclose()返回時hello和world未必已經成功發送到對方了如果我們設置了linger而不小於

  bool on = trueint linger = ……

  socketsetSoLinger(boolean on int linger)

  ……

  socketclose()那麼close會等到發送的數據已經確認了才返回但是如果對方宕機超時那麼會根據linger設定的時間返回

  UrgentData和OOBInline

  TCP的緊急指針一般都不建議使用而且不同的TCP/IP實現也不同一般說如果你有緊急數據寧願再建立一個新的TCP/IP連接發送數據讓對方緊急處理

  所以這兩個參數你們可以忽略吧想知道更多的自己查下資料

  SoTimeout

  設置socket調用InputStream讀數據的超時時間以毫秒為單位如果超過這個時候會拋出SocketTimeoutException

  KeepAlive

  keepalive不是說TCP的常連接當我們作為服務端一個客戶端連接上來如果設置了keeplive為true當對方沒有發送任何數據過來超過一個時間(看系統內核參數配置)那麼我們這邊會發送一個ack探測包發到對方探測雙方的TCP/IP連接是否有效(對方可能斷點斷網)在Linux好像這個時間是如果不設置那麼客戶端宕機時服務器永遠也不知道客戶端宕機了仍然保存這個失效的連接

  SendBufferSize和ReceiveBufferSize

  TCP發送緩存區和接收緩存區默認是一般情況下足夠了而且就算你增加了發送緩存區對方沒有增加它對應的接收緩沖那麼在TCP三握手時最後確定的最大發送窗口還是雙方最小的那個緩沖區就算你無視發了更多的數據那麼多出來的數據也會被丟棄除非雙方都協商好

  以上的參數都是比較重要的Java Socket參數了其他就不另外說明了


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26575.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.