TCP握手、传输、挥手

图:

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();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值