TCP三次握手

article/2025/10/1 18:03:47

TCP协议是传输层协议,是一种面向连接的传输控制协议,可以控制流量的传输。是一种可靠的传输,能够保证数据的完整性,有效性和有序性。

1.TCP建立连接(三次握手)

       

第一次握手:PC1发送SYN请求,序列号为随机生成的a,由于是第一次建立连接,所以ACK此时为0,flag字段中的SYN置位为1。

第二次握手 :PC2收到PC1的SYN请求,回复SYN ACK,序列号为随机生成的b,ACK为a+1,表示PC1发来的序列号为a的报文已经收到,同时希望PC1下次发来的报文序列号为a+1。因为TCP是一种双向连接所以,PC2发送给PC1的报文中flag位的SYN和ACK都置为1,既表示对PC1序列号为a的一种确认,又表示自己向PC1也发起SYN请求连接。

第三次握手:PC1收到PC2发来的序列号为b,ACK为a+1的SYN ACK报文,知道PC2已经收到PC1第一次发送的序列号为a的SYN,同时PC2发来了连接请求,PC1回复序列号为a+1,ACK为b+1的报文,表示对PC2发来的序列号为b的报文的确认,同时希望PC2下次发来的报文序列号为b+1。

前两次握手并不能携带数据,第三次握手可以携带数据。

第一次握手:PC1知道自己发送数据OK

第二次握手:PC2知道PC1发送数据OK,自己接收和发送数据OK

第三次握手:双方收发数据都OK,可以携带数据

实例演示:

         

模拟R1 telnet R2时,查看TCP建立连接的三次握手报文。

2.TCP保证数据的可靠性和有序性

        TCP通过序列号和确认序列号来保证数据的可靠性,完整性和有序性。

        1.当TCP连接建立完成后,R1向R2发送数据,发送的第一个数据包的序列号是a+1,确认序列号位b+1,携带128字节的数据。

        2.R2回复R1时,序列号为b+1,确认序列号位a+1+128,携带10字节的数据。此时R2的ack就是最近一次收到的R1数据包的序列号再加上数据的长度,表示对R1发来的序列号为a+1的128个字节数据的确认。

        3.R1再次给R2发送数据,序列号为a+139,确认序列号位b+11,携带10字节的数据。此时R1的ack就是最近一次收到的R2数据包的序列号再加上数据的长度,表示对R2发来的序列号为b+1的10个字节数据的确认。

        4.R2再次回复R1时,序列号为b+11,确认序列号位a+129+10,携带0字节的数据。此时R2的ack就是最近一次收到的R1数据包的序列号再加上数据的长度,表示对R1发来的序列号为a+129的10个字节数据的确认。

        5.R1再次给R2发送数据,序列号为a+139,确认序列号位b+11,携带10字节的数据。此时R1的ack就是最近一次收到的R2数据包的序列号再加上数据的长度,表示对R2发来的序列号为b+11的10个字节数据的确认。为什么此时R1的ack没有变化?因为最近一次收到R2发来的数据包没有携带数据,数据长度为0,因此R1的ack就是b+11+0。

 实例演示:

         

3.TCP的流量控制

        TCP通过window字段实现对数据流量的控制。

         1.假设两边的缓冲区大小都是3,在TCP建立阶段就会互相告知对方,自己这边的缓冲区大小是多少。

        2.PC1连续发送三个数据给PC2,此时PC2缓冲区占满,当上层应用拿走一个数据时,缓冲区空闲1。

        3.PC2回复PC1时,就会把自己空闲缓冲区大小告知给PC1。

        4.PC1收到PC2发来的确认,发现对方win字段为1了,那么再次发送数据时,就只能发送一次数据给PC2,但是自己这边的缓冲区大小不变,仍然为3,所以此时PC1发送的报文中,win字段仍然为3。

4.TCP断开连接(四次挥手)

        

        1.PC1发送FIN报文请求断开连接,flag位中FIN和ACK都置为1,seq=101,ack=301。

        2.PC2回复PC1的FIN请求,flag位中FIN和ACK都置为1,seq=301,ack=102。

        3.PC2也发送FIN报文请求断开连接,flag位中FIN和ACK都置为1,seq=301,ack=102。

        4.PC1回复PC2的FIN请求,flag位中FIN和ACK都置为1,seq=102,ack=302。


http://chatgpt.dhexx.cn/article/Lfb4yGSH.shtml

相关文章

TCP握手与挥手详解(附有图)

为什么不是4次握手 首先我们知道TCP是3次握手与4次挥手,为什么不是4次握手呢,因为其中握手请求同步过程中并不需要数据传输因此将两次合并为一次了。 我们需要掌握哪些标志量 SYN:请求同步标志,为1的时候为有效 ACK&#xff1…

为什么TCP需要握手

一、TCP握手流程 二、为什么不是4次握手 TCP的每次请求都是成对的,原则上应该是四次 【Client to Server】第一次SYN,seqx【Server to Client】第二次ACK,seqy,ackx1(没有携带数据的ACK不消耗序列号)【Se…

tcp_tw_recycle引起的TCP握手失败

背景 测试环境的一台Nginx服务器,最近一直被前端同事吐槽网络有问题,经常出现访问HTTP请求时超时,哪怕是静态文件也经常超时。 刚开始以为是公司网络抽风了,也就没放在心上,但持续了一个星期,而且复现率很…

TCP握手过程(正解版)

参考文章 Why do we need a 3-way handshake? Why not just 2-way https://blog.csdn.net/qq_36903042/article/details/102656641 https://blog.csdn.net/qq_36903042/article/details/102513465 大部分网络博客的错误解读 首先需要声明的是, 百度搜索到的大…

网络协议 (五) TCP握手建立连接

一、握手策略 为了可以准确的将数据准确无误地送达目标主机,所有基于 TCP 实现的协议,都需要先完成 TCP 协议的三次握手策略。 1. 首先我们需要了解一下图中提到的几个标志符: 1.序号seq seq 是TCP通信过程中,某一个传输方向上字…

TCP 握手没成功怎么办?

大家好,我是小林。 之前收到个读者的问题,对于 TCP 三次握手和四次挥手的一些疑问: 第一次握手,如果客户端发送的SYN一直都传不到被服务器,那么客户端是一直重发SYN到永久吗?客户端停止重发SYN的时机是什么…

深入理解TCP三次握手

一、TCP 包头格式 首先,TCP报文是TCP层传输的数据单元,也称为报文段,下面就是TCP包头格式: 接下来我们来看看每个字段的含义: 源端口和端口字号: TCP源端口:源计算机上应用程序端的端口号&…

TCP的三次握手及四次挥手详解

三次握手 三次握手过程: (1)第一次握手:Client将标志位SYN置为1(表示要发起一个连接),随机产生一个值seqJ,并将该数据包发送给Server,Client进入SYN_SENT状态&#xff0c…

C语言中main函数参数使用

在C99标准中定义main函数两种正确的写法 int main(void); int main(int argc, char* argv[]);常见的不标准写法 void main() main()这里主要说明带参数的main函数如何使用 int main(int argc, char* argv[]) {int i;for (i0; i<argc; i)printf("%d: %s\r\n", i…

C语言main函数参数、返回值

C语言main函数返回值&#xff1a; main函数的返回值&#xff0c;用于说明程序的退出状态。如果返回0&#xff0c;则代表程序正常退出&#xff1b;返回其他数字的含义则由系统决定&#xff0c;通常&#xff0c;返回非零代表程序异常退出&#xff0c;即使程序运行结果正确也仍需修…

main 函数的参数说明

C/C语言中的main函数&#xff0c;经常带有参数argc&#xff0c;argv&#xff0c;如下&#xff1a; int main(int argc, char** argv)int main(int argc, char* argv[])这两个参数的作用是什么呢&#xff1f;argc 是指命令行输入参数的个数&#xff0c;argv存储了所有的命令行参…

C++ main函数及main函数的参数

C main函数及main函数的参数 1、main函数的几种形式 int main() int main(int argc) int main(int argc,char** argv)//int main(int argc,char* argv[])2、argc表示命令行参数的个数、argv表示命令行参数的值 &#xff08;1&#xff09;写个小代码&#xff0c;用命令行运行…

带参数的main函数

支持C语言的系统允许main函数有两个参数 int main(int argc,char *argv[]){//argc表示从命令行传入的参数的个数&#xff1b;//argv表示从命令行传入的字符串数组&#xff1b; } 回显命令行参数 #include<stdio.h> int main(int argc,char *argv[]){int i;for(i0;i<…

main主函数参数解析

默认的main函数参数 int main(int argc, char *argv[]) {// 主函数的代码逻辑return 0; }其中&#xff0c;int 是主函数的返回值类型&#xff0c;主函数执行完后会返回一个整数值给操作系统&#xff0c;通常返回值为 0 表示程序正常结束&#xff0c;非 0 的返回值表示程序运行…

C语言main函数参数

常见的C语言的main函数都是不带参数的。因此main 后的括号都是空括号。实际上&#xff0c;main函数可以带参数&#xff0c;这个参数可以认为是main函数的形式参数。C语言规定main函数的参数只能有两个&#xff0c;习惯上这两个参数写为argc和argv。因此&#xff0c;main函数的函…

【C语言】main函数的参数

我们先看看主函数main的参数列表 #include <stdio.h>int main(int argc, char *argv[]) {return 0; }argc是一个整型变量&#xff0c;存储的是主函数的参数个数argv[]是一个字符型指针数组&#xff0c;其中存储的是主函数的参数字符串&#xff0c;是一个参数列表 注意:…

C++中main函数的参数

C中main函数的参数 问题 对于一个C/CPP文件来说&#xff0c;一般都有main函数&#xff0c;一个程序的执行一定会是先从main函数这个入口开始&#xff0c;一个最基本的程序框架大概长这样: #include <stdio.h> int main() {return 0; }但是&#xff0c;我们有时候看到的…

C++ main函数的参数

int main(int argc, char* argv[]) 那main函数的argc和argv参数是什么意思呢&#xff1f; 这两个参数主要是用来保存程序运行时传递给main函数的命令行参数的。 argc&#xff1a;是argument count 的缩写&#xff0c;保存运行时传递给main函数的参数个数。 argv&#xff1a;是…

main函数的参数的含义

转载自&#xff1a;点击链接 链接2 加qq1126137994 微信&#xff1a;liu1126137994 一起学习更多技术&#xff01;&#xff01;&#xff01; 最近学习服务器网络编程&#xff0c;遇到了一个问题&#xff0c;main函数的参数&#xff0c;特意整理资料记录之&#xff01;&#…

C++main函数及参数

转载自&#xff1a;https://www.cnblogs.com/carsonzhu/p/5276317.html C main()函数及其参数 1、首先&#xff0c;想想C/C在main函数之前和之后会做些什么&#xff1f; 我们看看底层的汇编代码&#xff1a; __start: :      init stack;      init heap;     …