关于TCP/IP 协议的几个经典问题

关于TCP/IP 协议的经典问题

1. 讲一下TCP三次握手的流程

一开始的时候,客户端和服务器都处于CLOSED的状态,然后服务器开始监听某个端口,进入LISTEN状态:

​ 三次握手,首先由客户端向服务端发起连接请求,此为第一次握手;

​ 然后服务端接收到来自客户端的请求之后,向客户端回复已经收到连接请求了,可以开始连接了,并转为等待连接模式,此为第二次握手;

​ 当客户端收到来自服务端的确认码之后,在次向客户端发送确认消息,并开始连接,此为第三次握手;

第一次握手(由客户端发出SYN = 1,seq = x),发送完毕后客户端处于SYN_SEND状态
第二次握手(有服务器发出SYN = 1,ACK = 1,seq = y,ACKnum = x+1)发送完毕后,发送完毕后服务器端进入SYN_RCVD状态
第三次握手(由客户端发出ACK = 1,ACKnum = y+1)发送完毕后客户端进入ESTABLISHED的状态,当服务器端接收到这个包时,也进入ESTABLISHED状态,TCP握手完成,可以开始进行数据传输。

2. TCP握手为什么是三次,不能是两次?也不能是四次?

三次握手是为了确保连接的成功,客户端和服务端都确认可以被连接然后第三次握手建立连接,如果是两次,那么建立的连接就不是百分百准确的,有可能连接失败;四次的话就有点多余了,既然三次握手已经能够准确的建立连接了,没必要再来一次,浪费时间和空间。

3.讲一下TCP四次挥手的过程

初始状态为客户端和服务端处于连接状态,并且数据已经发送完毕,没有要继续发送的数据了,然后客户端要开始断开连接:

客户端首先要向服务端发送消息,告诉服务器端,我没有要传输的数据了,可以进行断开了,此为第一次挥手;当服务器端收到来自客户端的消息之后,回复客户端他已经知道了,准备好了挥手,此为第二次回收;当发送完消息一段时间之后,服务器端发送消息告诉客户端我已经准备好了,可以进行断开了,此为第三次挥手;当客户端收到消息之后,客户端断开与服务端的连接,此为第四次挥手,至此,客户端和服务端的连接彻底断开;

1. 第一次挥手(FIN=1,seq=u),发送完毕后,客户端进入FIN_WAIT_1 状态
2. 第二次挥手(ACK=1,ack=u+1,seq =v),发送完毕后,服务器端进入CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态
3. 第三次挥手(FIN=1,ACK1,seq=w,ack=u+1),发送完毕后,服务器端进入LAST_ACK 状态,等待来自客户端的最后一个ACK。
4. 第四次挥手(ACK=1,seq=u+1,ack=w+1),客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。

4.为什么TCP挥手需要四次呢?

TCP的四次挥手过程就像两个人在打电话,当A对B说我没什么要说的了,B回复说我知道了;此时B可能还有话对A说,当B说完之后,B告诉A我说完了,你可以挂了,然后再有A来挂断电话。因为TCP通信是双端通信,客户端和服务端都可以向对方发送消息,所以要确定两边都没有数据可发送了之后才能彻底断开连接,因此需要四次挥手;

5.TIME_WAIT状态为什么需要等待2MSL

2msl 两个报文的生命周期

  1. 第一个MSL是为了能够保证四次挥手过程中的主动关闭方的ACK报文能够到达对端
  2. 第二个MSL是为了保证对端没收到ACK那么进行重传的FIN能够到达。

6.TCP和UDP的区别

  1. TCP是面向链接的(如打电话之前要先拨号),UDP是无连接的,及传递数据之间不需要建立连接;
  2. TCP要求安全性,提供可靠的服务,通过TCP连接传递的数据不丢失,不重复,安全可靠;但是UDP是尽最大努力交付,既不保障可靠交付;
  3. TCP是点对点连接,UDP可以是一对一、一对多、多对多都可以;
  4. TCP的传输效率相对UDP比较低,UDP适合对高速传输和对实时性有要求的通信。
  5. TCP适合用于网页,邮件等;UDP适合用于视频,语音广播等
  6. TCP面向字节流,UDP面向报文。

7.半连接队列和SYN flood攻击的关系

TCP进入三次握手前,服务端会从CLOSED状态变成LISTEN状态,同时在内部创建两个队列:半连接队列(SYN队列和全连接队列(ACCEPT队列)。

什么是半连接队列:

TCP三次握手是,客户端发送SYN到服务端,服务端收到后,便回复SYN和ACK,状态由LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列,及半连接队列。

什么是全连接队列:

当客户端回复SCK,服务端接收后,三次握手就完成了。这是链接会等待被具体的应用取走,再被取走之前,它被推入ACCEPT队列,即为全连接队列。

SYNFlood是一种典型的DOS(Denial of Service拒绝服务)攻击,她在短时间内,伪造不存在的IP地址,向服务器大量发起SYN报文,当服务器回复SYN+ACK报文后,不会受到ACK会议康报文,导致服务器上建立了当量的半连接,半连接队列被挤占满了就无法处理正产的TCP请求了。

8.TCP的粘包和拆包

TCP是面向流,没有界限的一串数据。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包进行发送,这就是所谓的TCP粘包和拆包问题。

为什么会产生粘包和拆包问题?
  • 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会产生粘包;
  • 接受数据段的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
  • 要发送的数据大于TCP发送缓冲区剩余空间的大小,将会发生拆包;
  • 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。及TCP报文长度-TCP头部长度 >MSS。
解决方案
  • 发送端将每个数据包封装成固定长度
  • 在数据的尾部增加特殊字符进行分割
  • 讲述分成两部分,一部分是头部一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值