13发送缓冲区、滑动窗口 对小于mss的包是如何拆包的
由于在之前的例子中,我们可以看到腾讯server返回的mss都是1460,windowsize 1152(接收端读缓冲,发送端写缓冲),故我们设计包大小为1300,以体现超过1152缓冲区的包,会被拆包,另外我们将客户端写入缓冲区分别设置为100和1300
1 先考虑发送缓冲区拆包,写入缓冲区100
package com.jds.test.bio.p8;
/**
* https://www.cnblogs.com/silyvin/articles/12037918.html
* Created by joyce on 2019/11/26.
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static final int PORT = 12123;
public static final int BUFFER_SIZE = 1300;
public static void main(String []f) throws IOException {
new Client().client();
}
//客户端代码
public void client() throws UnknownHostException, IOException{
final String s1 = "49.235.75.155";// tx
final String s2 = "localhost";
final String s3 = "39.100.99.222";// al
// Socket s = new Socket(s1,PORT);//创建socket连接
Socket s = new Socket();
System.out.println(s.getReceiveBufferSize());
System.out.println(s.getSendBufferSize());
s.setReceiveBufferSize(100);
// 这个100会先于滑动窗口导致拆包
// s.setSendBufferSize(100);
s.setSendBufferSize(BUFFER_SIZE);
s.connect(new InetSocketAddress(s1, PORT));
// 发送一个介于对方window 1152,与mss 1460的之间大小的包
s.getOutputStream().write(new byte[BUFFER_SIZE]);
}
}
package com.jds.test.bio.p8;
/**
* https://www.cnblogs.com/silyvin/articles/12037918.html
* Created by joyce on 2019/11/26.
*/
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final int PORT = 12123;
public static final int BUFFER_SIZE = 500;
public static void main(String [] f) throws IOException, InterruptedException {
new Server().server();
}
//服务端代码
public void server() throws IOException, InterruptedException{
// ServerSocket ss = new ServerSocket(PORT);
ServerSocket ss = new ServerSocket();
System.out.println(ss.getReceiveBufferSize());
ss.setReceiveBufferSize(100);
InetAddress bindAddr = null;
ss.bind(new InetSocketAddress(bindAddr, PORT), 50);
while(true) {
Socket s = ss.accept();
System.out.println(s.getRemoteSocketAddress().toString());
InputStream inputStream = s.getInputStream();
byte [] bytes = new byte[BUFFER_SIZE];
int i=0;
while (inputStream.read(bytes) != -1) {
System.out.println(i++);
}
}
}
}
服务端:
43690
/183.192.17.180:26573
0
1
2
3
4
5
6
7
8
9
10
11
12
客户端:
131072
131072

1)可见,1300的包被拆为13个100的包,服务端历次windowsize为1152-100=1052
2)在100/1152这个比例下,服务端全程未delayed ack
2 将写入缓冲区调整为1300,考察滑动窗口1152对拆包的影响

1)可见,1152的滑动窗口把原本1300字节的包拆为1152+148,这个包虽然跨过了1300发送缓冲区大小的坎,但被滑动窗口拦下,拆了
2)服务端输出:
43690
/183.192.17.180:26595
0 第1个1152包的第一个500字节
1 第1个1152包的第二个500字节
2 第1个1152包的第三个152字节
3 第2个148字节的包
3)虽然仅修改了mac client 发送缓冲区由100到1300,但是发送端的滑动窗口由17496到了39000
结论:
1 发送缓冲区首先会拆包
2 接着滑动窗口会拆包
浙公网安备 33010602011771号