日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

TCP的拥塞

發(fā)布時(shí)間:2024/9/30 编程问答 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP的拥塞 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

先看一個(gè)演示
服務(wù)端代碼:

package io.unittest;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException;/*** Author: ljf* CreatedAt: 2021/3/28 上午10:05*/ public class SocketIOProperties {private static final int RECEIVE_BUFFER = 10;private static final int SO_TIMEOUT = 0;private static final boolean REUSE_ADDR = false;private static final int BACK_LOG = 2; // 連接的等待隊(duì)列滿了之后還能拍幾個(gè),linux一切皆文件嘛,意味著等著不分配文件描述符的有兩個(gè)private static final boolean CLI_KEEPALIVE = false;private static final boolean CLI_OOB = false;private static final int CLi_REC_BUF = 20;private static final boolean CLI_REUSE_ADDR = false;private static final int CLI_SEND_BUF = 20;private static final boolean CLI_LINGER = true; // 服務(wù)關(guān)閉后端口是否立即釋放private static final int CLI_LINGER_N = 0;private static final int CLI_TIMEOUT = 0;private static final boolean CLI_NO_DELAY = false;public static void main(String[] args) {ServerSocket server = null;try {server = new ServerSocket();server.bind(new InetSocketAddress(9090), BACK_LOG);server.setReceiveBufferSize(RECEIVE_BUFFER);server.setReuseAddress(REUSE_ADDR);server.setSoTimeout(SO_TIMEOUT);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}System.out.println("server up use 9090 !");try {while (true) {System.in.read(); // 這里阻塞住,看沒(méi)有客戶(hù)端的情況下,server端怎么處理連接Socket client = server.accept();System.out.println("client port: " + client.getPort());client.setKeepAlive(CLI_KEEPALIVE);client.setOOBInline(CLI_OOB);client.setReceiveBufferSize(CLi_REC_BUF);client.setReuseAddress(CLI_REUSE_ADDR);client.setSendBufferSize(CLI_SEND_BUF);client.setSoLinger(CLI_LINGER, CLI_LINGER_N);client.setSoTimeout(CLI_TIMEOUT);client.setTcpNoDelay(CLI_NO_DELAY);// client.read //阻塞 沒(méi)有 -1 0new Thread(() -> {try {InputStream in = client.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));char[] data = new char[1024];while (true) {int num = reader.read();if (num > 0) {System.out.println("client read some data is : " + num + " val :" + new String(data, 0, num));} else if (num == 0) {System.out.println("client readed nothing!");continue;} else {System.out.println("client readed -1 ..."); // 客戶(hù)端斷開(kāi),就是-1System.in.read();break;}}} catch (IOException e) {e.printStackTrace();}}).start();}} catch (IOException e) {e.printStackTrace();} finally {try {server.close();} catch (IOException e) {e.printStackTrace();}}} }

有System.in.read(),阻塞
啟動(dòng)服務(wù)端程序,阻塞主,沒(méi)有應(yīng)用程序接收,這時(shí)候緩沖區(qū)大小是0,

這時(shí)候啟動(dòng)一個(gè)客戶(hù)端,模擬客戶(hù)端發(fā)送數(shù)據(jù),這時(shí)候緩沖區(qū)開(kāi)始漲了

不夠,繼續(xù)發(fā)到緩沖區(qū)撐爆,比如我發(fā)到1152就不漲了

那么既然不漲了,多發(fā)的數(shù)據(jù)就被丟棄了,那是丟掉了頭部的還是尾部的呢,這時(shí)候服務(wù)端回車(chē),跳過(guò)阻塞,接收數(shù)據(jù),發(fā)現(xiàn)是尾部的被丟掉了。即tcp的擁塞。

tcp怎么解決擁塞

窗口機(jī)制,還是上邊那個(gè)服務(wù)器阻塞的模型,看圖


客戶(hù)端連接的時(shí)候告訴,我有多少個(gè)窗口 win,數(shù)據(jù)包是多大 mss(1460,是ifconfig里mtu的1500減去ip和端口各占的20個(gè)字節(jié)) ,然后服務(wù)端告訴客戶(hù)端自己的win和mss,然后客戶(hù)端確認(rèn),然后連接建立,就通信。
在每次的通信數(shù)據(jù)交互過(guò)程中,客戶(hù)端和和服務(wù)端都告訴自己的窗口還有多少,如果服務(wù)端的窗口不夠用了,就阻塞住,直到數(shù)據(jù)處理完(交給應(yīng)用程序進(jìn)行下一步的處理),有空閑的窗口了就給客戶(hù)端發(fā)一個(gè)ack包通知隊(duì)列有剩余了,客戶(hù)端才繼續(xù)發(fā)包給服務(wù)端。反過(guò)來(lái)客戶(hù)端同理。就保證了tcp的包不能丟失。即擁塞控制

總結(jié)

以上是生活随笔為你收集整理的TCP的拥塞的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。