tcp三次握手题目(tcp三次握手面试题)

TCP的报头:1.源端口号:表示发送端端口号,字段长为16位。2.目标端口号:表示接收端口号,字段长为16位。3.序列号:表示发送数据的位置,字段长为32位。每发送一次数据,就累加一次该数据字节数的大小。注意:序列号不会从0或1开始,而是在建立连接时由计算机生成的一个随机数作为其初始值,通过SYN包发送给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。…

大家好,又见面了,我是你们的朋友全栈君。

#TCP的报头:
这里写图片描述

  1. 源端口号:表示发送端端口号,字段长为16位。
  2. 目标端口号:表示接收端口号,字段长为16位。
  3. 序列号:表示发送数据的位置,字段长为32位。每发送一次数据,就累加一次该数据字节数的大小。
    注意:序列号不会从0或1开始,而是在建立连接时由计算机生成的一个随机数作为其初始值,通过SYN包发送给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。
  4. 确认应答号:表示下一次应该收到的数据的序列号,字段长为32字节。发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。

序号的优点:

(1)保证报文按序到达。
(2)保证可靠性。
(3)保证效率。
(4)精准的报告哪些报文已经收到,哪些需要重传。

  1. 首部长度:该字段长度为4位,单位为4字节(32位)。TCP首部长度不包括选项的话,是20个字节,20/4=5,5的二进制序列:0101,报头长度也叫数据偏移,所以该字段可以设置为5,选项字段最大的是40字节,所以,TCP首部长度为最大为20+40=60字节,该字段可以设置的最大长度为60/4=15。
  2. 保留:该字段主要是为了以后扩展时使用,其长度为4位。一般设置为0,即使收到的包在该字段不为0,此包也不会丢弃。
  3. 控制位:字段长为6,每一位从左到右分别为:URG、ACK、PSH、RST、SYN、FIN。当对应的值为1,表示有具体含义。
    字段|含义
    —|:—
    URG|紧急指针是否有效。为1,表示某一位需要被优先处理。
    ACK|确认号是否有效,一般置为1。
    PSH|提示接收端应用程序立即从TCP缓冲区把数据读走。
    RST|对方要求重新建立连接,复位。
    SYN|请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1.
    FIN|希望断开连接。
  4. 窗口大小:接收缓冲区的大小,TCP不允许发送超过此处所示大小的数据。
  5. 校验和:发送端填充,CRC校验,接收校验不通过,则认为数据有问题。和UDP的区别是,UDP校验的是数据本身,TCP校验的不仅包含TCP首部,而且包含TCP数据部分。
  6. 紧急指针:只有在URG为1时有效,该字段为1表示本报文的段中的紧急数据的指针。
  7. 选项:用于提高TCP的传输性能。需要根据首部长度进行控制,其最大长度为40字节。

我们在着重讲一下在三次握手和四次挥手中的用到序列号、确认号及标志位

1. 序列号seq

占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生,给字节编上序号后,就给每一个报文段指派一个序号,序列号seq就是这个报文段中的第一个字节的数据编号。

2. 确认号ack

占4个字节,期待收到对方下一个报文段的第一个数据字节的序号,序列号表示报文段携带数据的第一个字节的编号,而确认号指的是期望接受到下一个字节的编号,因此挡墙报文段最后一个字节的编号+1即是确认号。
##3. 确认ACK
占1个比特位,仅当ACK=1,确认号字段才有效。ACK=0,确认号无效。

4. 同步SYN

连接建立时用于同步序号。当SYN=1,ACK=0表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使用SYN=1,ACK=1.因此,SYN=1表示这是一个连接请求,或连接接收报文,SYN这个标志位只有在TCP建立连接才会被置为1,握手完成后SYN标志位被置为0.

5. 终止FIN

用来释放一个

TCP三次握手以及四次挥手的过程

在这里插入图片描述

三次握手的过程

step1:第一次握手

建立连接时,客户端发送SYN包到服务器,其中包含客户端的初始序号seq=x,并进入SYN_SENT状态,等待服务器确认。(其中,SYN=1,ACK=0,表示这是一个TCP连接请求数据报文;序号seq=x,表明传输数据时的第一个数据字节的序号是x)。

step2:第二次握手

服务器收到请求后,必须确认客户的数据包。同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。(其中确认报文段中,标识位SYN=1,ACK=1,表示这是一个TCP连接响应数据报文,并含服务端的初始序号seq(服务器)=y,以及服务器对客户端初始序号的确认号ack(服务器)=seq(客户端)+1=x+1)。

step3:第三次握手

客户端收到服务器的SYN+ACK包,向服务器发送一个序列号(seq=x+1),确认号为ack(客户端)=y+1,此包发送完毕,客户端和服务器进入ESTAB_LISHED(TCP连接成功)状态,完成三次握手。

未连接队列

在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包时,删除该条目,服务器进入ESTAB_LISHED状态。

常见面试题

1.为什么需要三次握手,两次不可以吗?或者四次、五次可以吗?
我们来分析一种特殊情况,假设客户端请求建立连接,发给服务器SYN包等待服务器确认,服务器收到确认后,如果是两次握手,假设服务器给客户端在第二次握手时发送数据,数据从服务器发出,服务器认为连接已经建立,但在发送数据的过程中数据丢失,客户端认为连接没有建立,会进行重传。假设每次发送的数据一直在丢失,客户端一直SYN,服务器就会产生多个无效连接,占用资源,这个时候服务器可能会挂掉。这个现象就是我们听过的“SYN的洪水攻击”。
总结:第三次握手是为了防止:如果客户端迟迟没有收到服务器返回确认报文,这时会放弃连接,重新启动一条连接请求,但问题是:服务器不知道客户端没有收到,所以他会收到两个连接,浪费连接开销。如果每次都是这样,就会浪费多个连接开销。

四次挥手过程(关闭客户端到服务器的连接)

step1:第一次挥手

首先,客户端发送一个FIN,用来关闭客户端到服务器的数据传送,然后等待服务器的确认。其中终止标志位FIN=1,序列号seq=u。

step2:第二次挥手

服务器收到这个FIN,它发送一个ACK,确认ack为收到的序号加一。

step3:第三次挥手

关闭服务器到客户端的连接,发送一个FIN给客户端。

step4:第四次挥手

客户端收到FIN后,并发回一个ACK报文确认,并将确认序号seq设置为收到序号加一。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

客户端发送FIN后,进入终止等待状态,服务器收到客户端连接释放报文段后,就立即给客户端发送确认,服务器就进入CLOSE_WAIT状态,此时TCP服务器进程就通知高层应用进程,因而从客户端到服务器的连接就释放了。此时是“半关闭状态”,即客户端不可以发送给服务器,服务器可以发送给客户端。
此时,如果服务器没有数据报发送给客户端,其应用程序就通知TCP释放连接,然后发送给客户端连接释放数据报,并等待确认。客户端发送确认后,进入TIME_WAIT状态,但是此时TCP连接还没有释放,然后经过等待计时器设置的2MSL后,才进入到CLOSED状态。

2.为什么需要2MSL时间?
首先,MSL即Maximum Segment Lifetime,就是最大报文生存时间,是任何报文在网络上的存在的最长时间,超过这个时间报文将被丢弃。《TCP/IP详解》中是这样描述的:MSL是任何报文段被丢弃前在网络内的最长时间。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒、1分钟、2分钟等。

TCP的TIME_WAIT需要等待2MSL,当TCP的一端发起主动关闭,三次挥手完成后发送第四次挥手的ACK包后就进入这个状态,等待2MSL时间主要目的是:防止最后一个ACK包对方没有收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可以继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。

3.为什么是四次挥手,而不是三次或是五次、六次?
双方关闭连接要经过双方都同意。所以,首先是客服端给服务器发送FIN,要求关闭连接,服务器收到后会发送一个ACK进行确认。服务器然后再发送一个FIN,客户端发送ACK确认,并进入TIME_WAIT状态。等待2MSL后自动关闭。

总结:
(1)为了保证客户端发送的最后一个ACK报文段能够到达服务器。即最后一个确认报文可能丢失,服务器会超时重传,然后服务器发送FIN请求关闭连接,客户端发送ACK确认。一个来回是两个报文生命周期。

如果没有等待时间,发送完确认报文段就立即释放连接的话,服务器就无法重传,因此也就收不到确认,就无法按步骤进入CLOSED状态,即必须收到确认才能close。
(2)防止已经失效的连接请求报文出现在连接中。经过2MSL,在这个连续持续的时间内,产生的所有报文段就可以都从网络消失。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/129754.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 中缀表达式转换为后缀表达式(栈的使用)

    中缀表达式如1*2+(2-1), 其运算符一般出现在操作数之间, 因此称为中缀表达式,也就是大家编程中写的表达式。编译系统不考虑表达式的优先级别, 只是对表达式从左到右进行扫描, 当遇到运算符时, 就把其前面的两个操作数取出, 进行操作。为达到上述目的, 就要将中缀表达式进行改写,变为后缀表达式 如上面的表达式1*2+(2-1), 就变为12*21-+;后缀表达式中不含有括号, 且

  • python中保留小数位数_python取小数部分

    python中保留小数位数_python取小数部分一.format方法a=1.23455print(format(a,’.2f’))print(format(a,’.4f’))符合四舍五入print(‘{:.2f}{:.3f}’.format(1.23455,1.23455))使用{}作为占位符,可以同时操作多个数字二.’%2f’%f方法a=1.23455print(‘%.4f’%a)符合四舍五入三.round()方法a=1.23455print(round(a,2))print(round(a,4))

  • C#textbox 密码输入框「建议收藏」

    C#textbox 密码输入框「建议收藏」C#textbox密码输入框C#中,怎么让textbox输入数字时显示为*号,因为用它作为验证输入密码设置TextBox的PasswordChar属性为*

  • Altium Designer初学教程(一)[通俗易懂]

    Altium Designer初学教程(一)[通俗易懂]安装说明及如何激活并申请添加license安装说明及如何激活并申请添加license我们提供的安装光盘可以在每台电脑上安装AltiumDesigner软件。我们为每个单位或公司产生一个用户号,我们为每台电脑产生一个激活码,用户在软件的license界面里输入用户号和激活码,软件将自动产生本机的一个二进制信息文件,用这个信息文件通过电子邮件到我们的服务器上换取本机的licens…

  • 使用reaver命令穷举PIN码破解WPA2-PSK加密的无线网络[通俗易懂]

    使用reaver命令穷举PIN码破解WPA2-PSK加密的无线网络[通俗易懂]【前言】现在的路由器大多都默认用WPA2-PSK方式对无线网络进行加密了,不能再像WEP加密方式那样好破解,使用字典又需要费心费力地整理字典,而且字典破解的效率还慢。所以我们需要更有效率的破解方法。好在现在大多数的路由器都提供WPS功能,通过这个功能,用户可以使用PIN码登录到路由器。但这个PIN码的长度只有8位,而且可能的取值只有11000种(注意,不是10…

  • 生产环境数据库并发数的调整

    生产环境数据库并发数的调整在开发和测试时,我们往往不会很在意数据库相关的一些并发数的配置,因为开发和测试时,系统的并发量并不会很大,因此,是否正确设置这些参数也不会对结果造成什么影响但是,上生产环境后,系统的并发量大大提高,这时,没有注意数据库的并发数配置的话就会使数据库成为系统最终的并发瓶颈。根据我在实际项目中一段时间的并发测试后,发现关于数据库并发数需要配置的几个地方,希望跟大家分享一下,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号