图:
java代码模拟:
public class TcpSimulator {
private int serverSequenceNumber = 1000;
private int clientSequenceNumber = 500;
private final int win = 512;
private int clientAck = 1;
private int serverAck = 1;
private int clientSeq = 1;
private int serverSeq = 1;
private void threeWayHandshake() throws InterruptedException {
System.out.println("Server: 等待从客户端来的SYN报文...");
TimeUnit.SECONDS.sleep(1);
String synPacket = "SYN: " + "seq:" + clientSequenceNumber + " ,win:" + 65495 + " ,length: " + 0;
System.out.println("Client: 向服务端发送 " + synPacket + " 请求建立连接...");
TimeUnit.SECONDS.sleep(1);
clientSequenceNumber++;
//TODO 为什么最开始的两次握手的win窗口大小65495那么大,到开始datatransfer的时候就变成512那么小
String synAckPacket = "SYN-ACK: " + "seq: " + serverSequenceNumber + " ,ack: " + clientSequenceNumber + " ,win:" + 65495 + " ,length: " + 0;
System.out.println("Server: 发送 " + synAckPacket + " 到客户端,确认收到");
TimeUnit.SECONDS.sleep(1);
serverSequenceNumber++;
String clientAckPacket = "ACK: " + " ack: " + clientAck + " ,win: " + win + " ,length: " + 0;
System.out.println("Client: 发送 " + clientAckPacket + " 到服务端,确认收到");
TimeUnit.SECONDS.sleep(1);
System.out.println("Server: 三次握手结束");
System.out.println("Client: 三次握手结束,链接建立\n");
}
private int dataTransfer() throws InterruptedException {
System.out.println("开始传输数据...");
String dataToSend = "Hello, server! How are you?";
int dataSize = dataToSend.getBytes().length;
if (dataSize > win) {
//滑动窗口一部分一部分地传输
}
int endIndex = clientSeq + dataSize;
String serverPshPacket = "PSH-ACK: " + " seq: " + clientSeq + ":" + endIndex + " ,ack:" + clientAck + " ,win:" + win + " ,length:" + dataSize + " ,data:" + dataToSend;
System.out.println("Client: 发送数据 " + serverPshPacket + "到服务端");
clientSeq = endIndex;
TimeUnit.SECONDS.sleep(1);
serverAck = endIndex;
String clientAckPacket = "ACK: " + "ack: " + serverAck + " ,win: " + win + " ,length: " + 0;
System.out.println("Server: 发送响应" + clientAckPacket + "到客户端");
TimeUnit.SECONDS.sleep(1);
dataToSend = "Hello, client! I'm fine,thank you! And you?";
dataSize = dataToSend.getBytes().length;
endIndex = serverSeq + dataSize;
String clientPshPacket = "PSH-ACK: " + " seq: " + serverSeq + ":" + endIndex + " ,ack: " + serverAck + " ,win:" + win + " ,length:" + dataSize + " ,data:" + dataToSend;
System.out.println("Server: 发送数据" + clientPshPacket + "到客户端");
serverSeq = endIndex;
TimeUnit.SECONDS.sleep(1);
clientAck = endIndex;
String serverAckPacket = "ACK: " + "ack: " + clientAck + " ,win: " + win + " ,length: " + 0;
System.out.println("Client: 发送响应" + serverAckPacket + "到服务端");
return endIndex;
}
private void releaseConnection() throws InterruptedException {
//14:13:20.503111 IP localhost.56978 > localhost.12345: Flags [F.], seq 15, ack 1, win 512, options [nop,nop,TS val 224911351 ecr 224911351], length 0
//14:13:20.503202 IP localhost.12345 > localhost.56978: Flags [F.], seq 1, ack 16, win 512, options [nop,nop,TS val 224911352 ecr 224911351], length 0
//14:13:20.503213 IP localhost.56978 > localhost.12345: Flags [.], ack 2, win 512, options [nop,nop,TS val 224911352 ecr 224911352], length 0
System.out.println("\n断开连接...");
String serverFinPacket = " FIN-ACK: " + "seq:" + clientSeq + " ,ack: " + clientAck + " ,win:" + win + " ,length: " + 0;
System.out.println("Client: 发送 " + serverFinPacket + " 到服务端");
TimeUnit.SECONDS.sleep(1);
serverAck = clientSeq + 1;
String clientAckPacketA = "ACK: " + "ack: " + serverAck + " ,win: " + win + " ,length: " + 0;
System.out.println("Server: 发送 " + clientAckPacketA + " 到客户端");
String clientAckPacketB = "FIN-PSH: " + "seq: " + serverSeq + " ,ack:" + serverAck + " ,length: " + 0;
System.out.println("Server: 发送 " + clientAckPacketB + " 到客户端 ");
TimeUnit.SECONDS.sleep(1);
clientAck = serverSeq + 1;
String serverAckPacket = "ACK: " + "ack:" + clientAck + " ,length: " + 0;
System.out.println("Client: 发送 " + serverAckPacket + " 到服务端端 ");
System.out.println("Client: 等待 2*MSL...");
TimeUnit.SECONDS.sleep(1);
System.out.println("Server: 连接释放.四次挥手结束");
TimeUnit.SECONDS.sleep(1);
System.out.println("Client: 连接释放.四次挥手结束,连接断开");
}
public void simulate() throws InterruptedException {
System.out.println("模仿TCP连接,传输,断开:\n");
threeWayHandshake();
dataTransfer();
releaseConnection();
}
public static void main(String[] args) throws InterruptedException {
TcpSimulator tcpSimulator = new TcpSimulator();
tcpSimulator.simulate();
}
}