【Java 网络编程】客户端 Socket 配置 ( 超时时间 | 端口复用 | Nagle 算法 | 心跳包机制 | 连接关闭机制 | 缓冲区大小 | 性能权重设置 | 紧急数据设置 )
文章目錄
- I 設置讀取超時時間
- II Socket 復用綁定端口設置
- III 開啟 Nagle 算法 ( 沾包 )
- IV 心跳包機制
- V 連接關閉處理
- VI Socket 緊急數據內斂設置
- VII Socket 設置緩沖區大小
- VIII Socket 連接性能參數設置
I 設置讀取超時時間
1. 設置 Socket 超時時間 , 該超時時間沒有實際的概念 , 用于設置與阻塞相關操作的超時時間 , TCP 連接中有兩個需要阻塞的操作 :
- ① 連接服務器操作 ;
- ② 等待讀取服務器發送給客戶端的數據 ;
連接超時時間可以單獨設置 , 這里設置的讀取超時時間 ;
2. 單位 : 毫秒 ( ms ) ;
3. 設置一個非 0 的超時時間 , 當與 Socket 對象關聯的 InputStream 輸入流執行 read() 操作時 , 其阻塞時間為這個超時時間 , 如果超過了該時間還沒有收到任何數據 , 就會拋出異常 ;
socket.setSoTimeout(3000);II Socket 復用綁定端口設置
設置是否可以復用 Socket 綁定的地址和端口號 : setReuseAddress( true ) ;
socket.setReuseAddress(true);Socket 連接在建立時 , 會使用之前綁定本地的 IP 地址和端口號 , 這個端口號在使用之后 , 2 分鐘之內不允許再次使用 ; 進行了該設置之后 , 可以在連接關閉之后 , 馬上使用該本地 IP 地址和端口號 ;
III 開啟 Nagle 算法 ( 沾包 )
1. 前提 : TCP 發送數據后 , 接收方會反饋已經接受到的數據 ;
2. 示例 : 客戶端如果向服務器端發送 1 字節數據 , 服務器端需要反饋 ACK 信息 , ACK 的命令其大小要比傳輸的數據還要大 , 其消耗要高于實際的數據傳輸消耗 ;
3. Nagle 算法引入 : 為了避免上述情況的消耗 , 便有了 Nagle 算法 ;
- ① 服務器端處理 : 其原理是接收端接到數據后 , 如果數據很小 , 那就多接收幾個數據 , 然后將反饋信息一起回送給發送端 ;
- ② 客戶端處理 : 對應的客戶端處理便是一條數據發送之后 , 會等待服務器端反饋 , 然后這段時間內如果又有新的數據要發送 , 那么就會將這些數據緩存起來 , 等待前面的數據反饋信息回送之后 , 將發送端緩存的這些數據全部發送出去 ; 這樣就出現了沾包的情況 ;
4. Nagle 算法好處 : Nagle 算法有效的減少了因發送少量數據 , 而產生大量的 ACK 回送包的數據量 ; 優化網絡帶寬 ;
在需要低延遲傳輸的情況下是需要關閉該算法的 , 該算法會導致數據沾包情況出現 ;
socket.setTcpNoDelay(true);IV 心跳包機制
設置了 setKeepAlive(true) 之后的效果 : 如果 TCP 連接在 2 小時之內沒有數據傳輸 , 客戶端就會發送心跳包 , 服務器端會會送消息 , 如果客戶端沒有收到服務器端反饋信息 , 就認為該 TCP 連接已經斷開 , 客戶端會拋出異常信息 ;
//在長時間 ( 2 小時 ) 沒有數據交互 , 是否需要發送心跳包確認連接 socket.setKeepAlive(true);V 連接關閉處理
1. 連接關閉處理 : 對于連接關閉行為處理方式設置 , 調用 setSoLinger 函數設置 ;
2. 關閉情況說明 : 當 Socket 對象調用 close 方法關閉連接時 , 有可能緩沖區中還有數據沒有發送完成 , 這個方法就是用于處理這部分緩沖區數據的 ;
3. setSoLinger 函數原型 :
/*** Enable/disable {@link SocketOptions#SO_LINGER SO_LINGER} with the* specified linger time in seconds. The maximum timeout value is platform* specific.** The setting only affects socket close.** @param on whether or not to linger on.* @param linger how long to linger for, if on is true.* @exception SocketException if there is an error* in the underlying protocol, such as a TCP error.* @exception IllegalArgumentException if the linger value is negative.* @since 1.1* @see #getSoLinger()*/public void setSoLinger(boolean on, int linger) throws SocketException4. setSoLinger 參數解析 :
- ① boolean on : TCP 連接關閉處理功能是否打開 , 默認是關閉的 ( false ) ;
- ② int linger : Socket 調用 close 方法后 , 需要阻塞等待緩沖區數據發送的時間 , 單位毫秒 ;
5. 默認狀態 : 如果 boolean on 設置成false , 不處理連接的緩存數據 , 調用 close 會立刻關閉連接 , 系統底層會操作輸出流發送剩余緩存數據 , 將緩沖區中的數據發送給連接對方 ; 如果設置 false 不會產生阻塞操作 ;
6. 開啟連接關閉處理 : setSoLinger( true , 20 ) 情況 , 如果設置 boolean on 參數為 true , int linger 參數設置一個大于等于 0 的參數 , 那么在關閉的時候 , 阻塞 linger 毫秒 , 之后緩沖區如果還有數據 , 就會被丟棄 , 直接向連接對方發送結束命令 , 無需經過超時等待 ;
超時等待是數據達到對方并返回的最長等待時間 ( MSL ) ;
7. 開啟連接關閉處理 ( 不阻塞 ) : setSoLinger( true , 0 ) 情況 , 如果設置成 0 , 那么其后果是不阻塞 , 也不讓系統接管輸出流 , 立刻丟棄緩沖區數據 , 向對方發送 RST 命令 ;
VI Socket 緊急數據內斂設置
//設置緊急數據是否內斂 , 默認情況時 false 關閉的 ; socket.setOOBInline(true);
1. 緊急數據 : 緊急數據是 Socket 對象通過調用 sendUrgentData 發送出去的數據 ; 該方法參數是一個 int 值 , 僅有最低的 8 位是有效的 ;
2. 緊急數據透明特性 : 緊急數據默認情況下與上層的數據是隔離的 , 如客戶端給服務器端發送了一條緊急數據 , 服務器端照常接收處理普通數據 , 其不影響數據的接收與處理 , 也不知道客戶端發送了緊急數據 ;
3. 接收緊急數據 : 如果服務器端想要接收客戶端發送的緊急數據 , 那么需要在獲取 Socket 輸入流之前設置 socket.setOOBInline(true) , 才能在接收數據時 , 讀取到緊急數據 ;
4. 設置緊急數據 : setOOBInline 方法設置緊急數據是否內斂 , 默認情況時 false 關閉的 ;
5. 適用場景 : 使用緊急數據當做心跳包 ;
不建議設置緊急數據內斂 , 可能會影響實際數據的正確性 ;
VII Socket 設置緩沖區大小
1. 緩沖區大小設置包括兩個緩沖區設置 :
- ① 發送緩沖區設置 :
- ② 接收緩沖區設置 ;
2. 緩沖區作用 : 緩沖區大小默認 32 KB , 緩沖區大小不是要等到有 32 KB 數據才進行發送和接收 , 而是如果發送和接收的數據大于 32 KB , 如 33 KB , 就會將數據拆分成兩包 , 32 KB 和 1KB , 然后進行發送和接收操作 ;
注意設置一定要在連接之前設置 , 連接后設置時無效的 ;
VIII Socket 連接性能參數設置
1. 調用 Socket 對象的 setPerformancePreferences 方法 , 設置連接的性能參數 ; 連接有以下三個性能參數 :
- ① 連接時間 ;
- ② 往返延遲 ;
- ③ 帶寬 ;
2. 設置的是權重不是具體性能參數 : 設置的值不是具體的參數 , 而是連接的性能權重 , 對哪個性能要求比較高 ;
3. 連接時間 : 如果該 Socket 的連接很頻繁 , 連接后傳一個數據 , 馬上斷開 , 這時候比較看重連接時間性能 , 此時可以將第一個參數設置成 10 , 后兩個參數設置成 1 , 表示注重連接時間性能 ;
//設置 連接時間 性能參數較重要 socket.setPerformancePreferences(10, 1, 1);4. 往返延遲 : 如果開發的是網游服務器 , 此時對延遲很看重 , 這時候可以將第二個參數設置成比較高的權重 ;
//設置 往返延遲 性能參數較重要 socket.setPerformancePreferences(1, 10, 1);5. 帶寬 : 如果開發的是音視頻服務器 , 注重帶寬性能 , 此時需要將第三個參數設置成較高的權重 ;
//設置 帶寬 性能參數較重要 socket.setPerformancePreferences(1, 10, 1);6. 上面的延遲和帶寬的性能是互斥的 , 延遲低 , 就意味著很小的包就要發送一次 , 其帶寬就低了 , 延遲高了 , 每次積累很多數據才發送 , 其帶寬就相應的提高了 ;
7. 函數原型 :
/*** Sets performance preferences for this socket.** <p> Sockets use the TCP/IP protocol by default. Some implementations* may offer alternative protocols which have different performance* characteristics than TCP/IP. This method allows the application to* express its own preferences as to how these tradeoffs should be made* when the implementation chooses from the available protocols.** <p> Performance preferences are described by three integers* whose values indicate the relative importance of short connection time,* low latency, and high bandwidth. The absolute values of the integers* are irrelevant; in order to choose a protocol the values are simply* compared, with larger values indicating stronger preferences. Negative* values represent a lower priority than positive values. If the* application prefers short connection time over both low latency and high* bandwidth, for example, then it could invoke this method with the values* {@code (1, 0, 0)}. If the application prefers high bandwidth above low* latency, and low latency above short connection time, then it could* invoke this method with the values {@code (0, 1, 2)}.** <p> Invoking this method after this socket has been connected* will have no effect.** @param connectionTime* An {@code int} expressing the relative importance of a short* connection time** @param latency* An {@code int} expressing the relative importance of low* latency** @param bandwidth* An {@code int} expressing the relative importance of high* bandwidth** @since 1.5*/public void setPerformancePreferences(int connectionTime,int latency,int bandwidth) 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的【Java 网络编程】客户端 Socket 配置 ( 超时时间 | 端口复用 | Nagle 算法 | 心跳包机制 | 连接关闭机制 | 缓冲区大小 | 性能权重设置 | 紧急数据设置 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 网络编程】TCP 传输机制
- 下一篇: 【Java 网络编程】客户端 Socke