Wireshark文档阅读笔记-TCP 3 way handshaking解析与实例

这里先介绍2个概念:

TCB:Transmission Control Block,传输控制块,这个和PCB(进程控制块)类似,存储了很多重要的内容。如TCP连接表,发送缓存指针和接收缓存指针,重发队列指针,当前序列号和确认序列号(ACK)。

ACK包中带有“数据”,这个数据是指处理SYN(Synchronize Sequence Numbers同步序列号),确认包序列为seq=x+1,这个x是客户端或服务器传过来的。但在实际TCP3次握手中,不仅仅包含这些东西,还带有商议的内容如MSS(maximum segment size)等。

 

假设客户端和服务端目前都处于CLOSED状态。

流程图如下:

1. 服务端创建TCB,并且使用TCB接收客户端请求,当TCB建立起来后,服务端的状态会从CLOSED变为LISTEN。

2. 客户端也创建TCB,并且使用TCB发送请求,请求头中带有“SYN=1”,生成一个任意的随机数seq=x。SYN包(SYN设置为1的包称为SYN包),除了携带sql=x这个会被服务端处理的消息,不会携带其他消息。当请求发送后客户端会从CLOSED状态转变为SYN-SENT状态。

3. 服务端接收到客户端消息后:

    a. 如果服务端接收到客户端发起的连接(也就是这个消息),会回一个确认消息,在消息体中带有SYN和ACK,并且都会被置为1,服务端也会生成一个随机数seq=y,ack=x+1,这个x是客户端发过来的值,这个包里面只会包含刚刚说的那些数据。此时服务端的状态将变为SYN-RCVD。

    b. 如果服务端拒绝连接,将会发送RST包用于重置连接。

4. 客户端接收到服务端的响应,会发送一个确认包内容为ACK置为1,seq=x+1。

完成上面的操作后两个进程的状态都会转变为ESTABLISHED,这就是TCP的三次握手。

 

官方的例子如下:

点击下载

 

下面来分析下本人抓的包:

这里我们使用Java搭建一个Web服务端,请求的关键代码如下:

package cn.it1995.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/test")
    public String test(){

        return "test";
    }
}

用C++写个客户端,让其连接,获取数据,然后断开连接:

#include <QCoreApplication>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QUrl>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QNetworkAccessManager manager;
    QNetworkRequest request;
    request.setUrl(QUrl("http://127.0.0.1:8080/test"));
    QNetworkReply *reply = manager.get(request);
    QObject::connect(reply, &QNetworkReply::finished, [&](){

        qDebug() << reply->readAll();
        qApp->exit();
    });

    return a.exec();
}

此时抓到的包如下:

一开始客户端发了一个包将Seq=0。

服务端收到后返回Ack=0+1,而Seq=0这个0为服务端产生的随机数。

客户端接收到服务端的包后将Ack设置为1,Seq为0+1。这个0为服务端传过来的0。

 

相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页