面试常问TCP问题回答不上来?一篇深度讲解TCP文章看完让你面试
谈下你对五层网络协议体系结构的理解?
应用,主机,网络,数据,数据单位
- 应用层 - 应用间通信协议,不同应用使用不同协议 HTTP,SMTP
- 运输层 - 主机间通信服务,运输层复用、分用
- 网络层 - 选择合适 网间路由、交换结点,通过 多链路、多通信子网
- 数据链路层 - 切割报文,让他在链路上 一段段 传输
- 物理层 - 数据单位是比特,让比特流运输无视设备差异
应用层
应用层指的是完成应用进程间
的通信的网络协议
。应用层协议定义的是应用进程间
的通信和交互规则
。
对于不同的网络应用需要不同的应用层协议。如域名系统 DNS,互联网的 HTTP 协议,邮件的 SMTP 协议等等。
域名系统
域名系统(Domain Name System缩写DNS,Domain是因特网的一项核心服务,它作为可以将
域名和IP地址相互映射的分布式数据库
,能够使人不用去记住能够被机器直接读取的IP数串。
HTTP协议
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最广泛的网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。设计 HTTP 最初的目的是为了提供一种发布和接收 HTML 页面的方法。(百度百科)
运输层
运输层是完成两台主机进程之间
的通信提供通用的数据传输服务
。通用的
是指多种应用
可以使用同一个
运输层服务。
由于主机可同时运行多线程,因此运输层有复用
和分用
的功能。
- 复用就是指
多个应用
层进程可同时使用
下面运输层服务
。 - 分用是运输层把收到的信息
分别
交付上面应用层中的相应
进程。
运输层主要使用以下两种协议
- 传输控制协议 TCP(Transmisson Control Protocol)–提供面向连接的,可靠的数据传输服务。
- 用户数据协议 UDP(User Datagram Protocol)–提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
UDP 的主要特点
- UDP 是无连接的;
- UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数);
- UDP 是面向报文的;
- UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 直播,实时视频会议等);
- UDP 支持一对一、一对多、多对一和多对多的交互通信;
- UDP 的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
TCP 的主要特点
- TCP 是面向连接的。(就好像打电话一样,通话前需要先拨号建立连接,通话结束后要挂机释放连接);
- 每一条 TCP 连接只能有两个端点,每一条TCP连接只能是点对点的(一对一);
- TCP 提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达;
- TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双方通信的数据;
- 面向字节流。TCP 中的“流”(Stream)指的是流入进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。
TCP\UDP的区别
TCP提供可靠的通信传输 | UDP则常被用于让广播和细节控制交给应用的通信传输。
图片描述
网络层
主机间通信会经过多链路
,多通信子网
。网络层是选择
合适的网间路由
和交换结点
, 确保数据及时传送。
在发送数据时,网络层把运输层产生的报文段或用户数据报封装成分组和包进行传送。在 TCP / IP 体系结构中,由于网络层使用 IP 协议,因此分组也叫 IP 数据报,简称数据报。
数据链路层
数据
链路层简称为链路层。主机通信总是在一段一段
的链路上传送的,这就需要使用专门的链路层的协议。
传送数据时,数据链路层将数据报文组装成帧传输,每一帧包括数据和必要的控制信息(如:同步信息,地址信息,差错控制等)。
在接收数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。
数据链路层在收到一个帧后,就可从中提出数据部分,上交给网络层。
控制信息还使接收端能够
检测
到所收到的帧中有无差错
。如果发现差错,数据链路层就简单地丢弃
这个出了差错的帧,避免浪费网络资源。如果需要改正数据在链路层传输时出现差错(这就是说,数据链路层不仅要检错,而且还要纠错),那么就要采用可靠性传输协议来纠正出现的差错。这种方法会使链路层的协议复杂些。
物理层
在物理层上所传送的数据单位是比特。
物理层是实现
相邻节点之间比特流的透明传送
,尽可能屏蔽物理设备的差异。“透明传送比特流”表示经实际电路传送后的比特流没有发生变化
TCP 三次握手和四次挥手
图片描述TCP 三次握手 - 建立一个连接:
- 客户端–发送带有 SYN 标志的数据包给服务端 - 一次握手
- 服务端–发送带有 SYN/ACK 标志的数据包给客户端 – 二次握手
- 客户端–发送带有带有 ACK 标志的数据包给服务端 – 三次握手
什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。
当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
这里在补充一点关于SYN-ACK 重传次数的问题:
服务器发送完SYN-ACK包,如未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…
SYN攻击 - 典型的DDOS攻击之一
攻击原理:在三次握手中,Server发送SYN-ACK后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。
检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
netstat -nap | grep SYN_RECV
ISN(Initial Sequence Number)是固定的吗?
ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
三次握手过程中可以携带数据吗?
第一次、第二次握手不可以携带数据.第三次握手的时候,是可以携带数据的。
因为第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他重复在第一次握手中的 SYN 报文中放入大量的数据,这会让服务器花费很多时间、内存空间来接收这些报文。
简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常,能携带数据也没啥毛病
为什么要三次握手
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
- 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常
- 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己接收正常,对方发送正常
- 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送接收正常
所以三次握手就能确认双发收发功能都正常,缺一不可。
为什么要传回 SYN
接收端传回发送端所发送的 SYN 是为了告诉发送端,我接收到的信息确实就是你所发送的信号了。
传了 SYN,为啥还要传 ACK
双方通信无误必须是两者互相发送信息都无误。传了 SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要 ACK 信号来进行验证。
为什么不需要四次握手 -
完全可靠的通信协议是不存在的。在经过三次握手之后,客户端和服务端已经可以确认之前的通信状况,都收到了确认信息。所以即便再增加握手次数也不能保证后面的通信完全可靠,所以是没有必要的。
TCP 四次挥手 - 断开一个连接:
- 客户端-发送一个 FIN,用来关闭客户端到服务器的数据传送
- 服务器-收到这个 FIN,它发回一 个 ACK,确认序号为收到的序号加1 。和 SYN 一样,一个 FIN 将占用一个序号
- 服务器-关闭与客户端的连接,发送一个FIN给客户端
- 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1
为什么要四次挥手
ACK报文是用来应答的,SYN报文是用来同步的。
当服务端收到FIN报文时,并不会立即关闭SOCKET,只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
2MSL等待状态
TIME_WAIT状态也成为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
四次挥手释放连接时,等待2MSL的意义?
为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。
假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?
理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。