生活随笔
收集整理的这篇文章主要介绍了
TCP的拥塞
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
先看一个演示
服务端代码:
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
;
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; 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; 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(); 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
);new 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 ..."); System
.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(),阻塞
启动服务端程序,阻塞主,没有应用程序接收,这时候缓冲区大小是0,
这时候启动一个客户端,模拟客户端发送数据,这时候缓冲区开始涨了
不够,继续发到缓冲区撑爆,比如我发到1152就不涨了
那么既然不涨了,多发的数据就被丢弃了,那是丢掉了头部的还是尾部的呢,这时候服务端回车,跳过阻塞,接收数据,发现是尾部的被丢掉了。即tcp的拥塞。
tcp怎么解决拥塞
窗口机制,还是上边那个服务器阻塞的模型,看图
客户端连接的时候告诉,我有多少个窗口 win,数据包是多大 mss(1460,是ifconfig里mtu的1500减去ip和端口各占的20个字节) ,然后服务端告诉客户端自己的win和mss,然后客户端确认,然后连接建立,就通信。
在每次的通信数据交互过程中,客户端和和服务端都告诉自己的窗口还有多少,如果服务端的窗口不够用了,就阻塞住,直到数据处理完(交给应用程序进行下一步的处理),有空闲的窗口了就给客户端发一个ack包通知队列有剩余了,客户端才继续发包给服务端。反过来客户端同理。就保证了tcp的包不能丢失。即拥塞控制。
总结
以上是生活随笔为你收集整理的TCP的拥塞的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。