TCP面试大总结

  本文参考自 https://blog.csdn.net/u013591094/article/details/110315413

  一直想写一篇tcp的总结,主要就是应付面试的,因为tcp的知识点比较多不总结下每次都找真的是烦死人。刚好看到这篇文章,真的是良心文章正好能满足我的需要可谓是一拍即合啊。以后面试再有tcp的知识点,我就以这篇为准了,反正问我我就这么说,嘿嘿。

一 TCP的首部结构

  

  1. TCP首部结构先是16位的源端口号和目标端口号、接着是32位的序列号和确认号。

  2. 16位的属性则有窗口大小(控制发送窗口),检验和(校验数据段是否未被修改)及紧急指针。

  3. 详细说下序列号,它是TCP报文段的一数字编号,为保证TCP可靠连接,每一个发送的数据段都要加上序列号。建立连接时,两端都会随机生成一个初始序列号。而确认号而是和序列号配合使用的,应答某次请求时,则返回一个确认号,它的值等于对方请求序列号加1

  4. 6个标志位分别是,URG:这是条紧急信息,ACK:应答消息,PSH:缓冲区尚未填满,RST:重置连接,其实RST是用来关闭异常连接的,SYN:建立连接消息标志,FIN:连接关闭通知信息

  5. 窗口大小是接收端用来控制发送端的滑动窗口大小 (隐约有点印象发送数据的时候也会带着自身的滑动窗口用来接收)

二  TCP和UDP有什么区别

  TCP面向连接。UDP是无连接的,发送数据之前不需要建立连接

  TCP传输效率相对较低,UDP传输效率高

  TCP提供可靠的服务,保证传送的数据,无差错,不丢失,不重复,且按序到达。UDP则是尽最大努力交付,不保证可靠交付

三  TCP是可靠的连接,它是怎么实现的

  TCP的连接是基于三次握手,而断开则是四次挥手

  为了保障数据不丢失及错误(可靠性),它有报文校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制

四  具体说一说三次握手和四次挥手机制

  

  

五 如果没有三次握手会有什么问题呢

  如果只有两次握手,client发连接请求后不会再ACK服务端的SYN

  此时若客户端因为自身原因判断建立连接失败,可能会重复建立TCP连接,而服务端却会认为那些被client丢弃的TCP还是有效,会白白浪费资源

六 TIME_WAIT和CLOSE_WAIT的区别在哪

  CLOSE_WAIT是被动关闭形成的;当对方close socket而发送FIN报文过来时,回应ACK之后进入CLOSE_WAIT状态。随后检查是否存在未传输数据,如果没有则发起第三次挥手,发送FIN报文给对方,进入LAST_ACK状态并等待对方ACK报文到来

  TIME_WAIT是主动关闭连接方式形成的;处于FIN_WAIT_2状态时,收到对方FIN报文后进入TIME_WAIT状态;之后再等待两个MSL(Maximum Segment Lifetime:报文最大生存时间)

七 TIME_WAIT的作用呢,还有为啥状态时间要保持两个MSL

  1)TIME_WAIT的作用是为了保证最后一次挥手的ACK报文能送达给对方,如果ACK丢失,对方会超时重传FIN,主动关闭端会再次响应ACK过去;如果没有TIME_WAIT状态,直接关闭,对方重传的FIN报文则被响应一个RST报文,此RST会被动关闭端被解析成错误

  2)存在两个连接,第一个连接正常关闭,第二相同的连接紧接着建立;如果第一个连接的迷路报文到来,则会干扰第二连接,等待两个MSL则可以让上次连接的报文数据消逝在网络后。因为在TIME_WAIT状态的连接收到报文是不会响应的。

八 TCP协议用什么方式去解决拥塞的

  第一方式是慢启动和拥塞避免

  1)慢启动,TCP发送端会维护一个拥塞窗口(congestion window),简称为cwnd。拥塞窗口初始为1个报文段,每经过一次RTT(数据完全发送完到确认的时间),窗口大小翻倍(指数增长,只是前期慢)  

  2)拥塞避免,它思路是让拥塞窗口cwnd缓慢增大,发送方的cwnd达到阀值ssthresh(初始值由系统决定的)之后,每经过一个RTT就把拥塞窗口加一,而不是加倍(收到两个或四个确认,都是cwnd+1),cwnd呈线性增加(加法增大)

  

  如果遇到网络拥塞,拥塞窗口阀值ssthresh减半,cwnd设置为1,重新进入慢启动阶段。如何判断网络拥塞,主要是靠丢包,记住这个就行了

九 拥塞控制还有其他什么方式呢

  快重传和快恢复

  1)快重传是当接收方收到了一个失序的报文,则立马报告给发送方,赶紧重传

  假如接收方M1收到了,M2没有收到,之后的M3、M4、M5又发送了,此时接收方一共连续给发送方反馈了3个M1确认报文。那么快重传规定,发送方只要连续收到3个重复确认,立即重传对方发来的M2(重复确认报文的后一个报文)

  

  2)快恢复

  当发送方连续收到三个重复确认,ssthresh减半;由于发送方可能认为网络现在没有拥塞,因此与慢启动不同,把cwnd值设置为ssthresh减半之后的值,然后执行拥塞避免算法,cwnd线性增大

  

十 知道滑动窗口不,客户端和服务端控制滑动窗口的过程是怎样的

  接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK报文来通知发送端,滑动窗口是接收端用来控制发送端发送数据的大小,从而达到流量控制

  其实发送方的窗口上限,是取值拥塞窗口和滑动窗口两者的最小值

十一 那你知道滑动窗口和拥塞窗口有什么区别不

  相同点都是控制丢包现象,实现机制都是让发送方发得慢一点

  不同点在于控制的对象不同

  1)流量控制的对象是接收方,怕发送方发的太快,使得接收方来不及处理

  2)拥塞控制的对象是网络,怕发送方发的太快,造成网络拥塞,使得网络来不及处理

十二  TCP的粘包和拆包问题,你怎么看

  程序需要发送的数据大小和TCP报文段能发送MSS(Maximum Segment Size,最大报文长度)是不一样的

  大于MSS时,而需要把程序数据拆分为多个TCP报文段,称之为拆包;小于时,则会考虑合并多个程序数据为一个TCP报文段,则是粘包;其中MSS = TCP报文段长度-TCP首部长度

  在IP协议层或者链路层、物理层,都存在拆包、粘包现象

十三 那解决粘包和拆包的方法都有哪些?

  在数据尾部增加特殊字符进行分割

  将数据定为固定大小

  将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小

十四  SYN Flood了解吗

  SYN Flood 伪造 SYN 报文向服务器发起连接,服务器在收到报文后用 SYN_ACK 应答,此应答发出去后,不会收到 ACK 报文,造成一个半连接

  若攻击者发送大量这样的报文,会在被攻击主机上出现大量的半连接,耗尽其资源,使正常的用户无法访问,直到半连接超时

  

004: 说说半连接队列和 SYN Flood 攻击的关系

三次握手前,服务端的状态从CLOSED变为LISTEN, 同时在内部创建了两个队列:半连接队列全连接队列,即SYN队列ACCEPT队列

半连接队列

当客户端发送SYN到服务端,服务端收到以后回复ACKSYN,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,也就是半连接队列

全连接队列

当客户端返回ACK, 服务端接收后,三次握手完成。这个时候连接等待被具体的应用取走,在被取走之前,它会被推入另外一个 TCP 维护的队列,也就是全连接队列(Accept Queue)

SYN Flood 攻击原理

SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:

  1. 处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。

  2. 由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

如何应对 SYN Flood 攻击?

  1. 增加 SYN 连接,也就是增加半连接队列的容量。
  2. 减少 SYN + ACK 重试次数,避免大量的超时重发。
  3. 利用 SYN Cookie 技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证 Cookie 合法之后才分配连接资源。

十五  一次HTTP请求,程序一般经历了哪几个步骤?

  1)解析域名 -> 2)发起TCP三次握手,建立连接 -> 3)基于TCP发起HTTP请求 -> 4)服务器响应HTTP请求,并返回数据 -> 5)客户端解析返回数据

十六 一个TCP包多大

  我上学的时候背的数据链路层MTU是1500字节,ip层减20,tcp层再减20,所以TCP包最大字节数是1460  

posted on 2021-01-14 09:08  MaXianZhe  阅读(276)  评论(0编辑  收藏  举报

导航