概述
TCP连接
TCP作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高传输的效率,而用三次恰恰可以满足以上两方面的需求!
三次握手
-
Client首先发送一个连接试探,ACK=0 表示确认号无效,SYN = 1 表示这是一个连接请求或连接接受报文,同时表示这个数据报不能携带数据,seq = x 表示Client自己的初始序号(seq = 0 就代表这是第0号包),这时候Client进入syn_sent状态,表示客户端等待服务器的回复
-
Server监听到连接请求报文后,如同意建立连接,则向Client发送确认。
TCP报文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到对方下一个报文段的第一个数据字节序号是x+1,同时表明x为止的所有数据都已正确收到(ack=1其实是ack=0+1,也就是期望客户端的第1个包),seq = y 表示Server 自己的初始序号(seq=0就代表这是服务器这边发出的第0号包)。这时服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待client的确认。 -
Client收到确认后还需再次发送确认,同时携带要发送给Server的数据。ACK 置1 表示确认号ack= y + 1 有效(代表期望收到服务器的第1个包),Client自己的序号seq= x + 1(表示这就是我的第1个包,相对于第0个包来说的),一旦收到Client的确认之后,这个TCP连接就进入Established状态,就可以发起http请求了。
下面分别对其中的字段进行介绍:
源端口和目的端口
各占2个字节,这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时一个IP地址和一个端口号也称为socket(插口)。
序号(seq)
占4个字节,是本报文段所发送的数据项目组第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。例如,一报文段的序号为300,而且数据共100字节,
则下一个报文段的序号就是400;序号是32bit的无符号数,序号到达2^32-1后从0开始。
确认序号(ack)
占4字节,是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号;确认序号应该是上次已成功收到数据字节序号+1。
只有ACK标志为1时,确认序号才有效。
数据偏移
占4比特,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,
也就是4个字节,因此TCP首部的最大长度是60个字节。即偏移最大为15个长度单位=1532位=154字节。
保留
6比特,供以后应用,现在置为0。
6个标志位比特
① URG:当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,
使接管方可以知道紧急数据共有多长。
② ACK:只有当ACK=1时,确认序号字段才有效;
③ PSH:当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。
④ RST:当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接;
⑤ SYN:SYN=1,ACK=0时表示请求建立一个连接,携带SYN标志的TCP报文段为同步报文段;
⑥ FIN:发端完成发送任务。
窗口
TCP通过滑动窗口的概念来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制, 协调好
通信双方的工作节奏。所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓 冲区。窗口大小为
字节数起始于确认序号字段指明的值(这个值是接收端正期望接收的字节)。窗口大小是一个16bit字段,因而窗口大小最大为65535字节。
检验和
检验和覆盖了整个TCP报文段:TCP首部和数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
紧急指针
只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
为什么两次握手而不是三次?
两次握手弊端:第一次客户端向服务端发送请求,结果第一个请求在某个网络结点停滞了,没有立刻得到服务端的回应,客户端以为超时,所以客户端向服务端发第二次请求,这次得到了服务端的回应,建立连接,传输数据,结束后,这时第一个请求才到达了服务端,而服务端以为客户端又要建立一次连接,这时候服务端就一直准备着客户端发送数据过来,但没有,这就浪费了很多的资源,同时保证消息的保真和有序
三次握手的原则设计是防止旧复用链接的初始化导致问题
四次挥手
第一次挥手
TCP发送一个FIN(结束),用来关闭客户到服务端的连接。
客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),
此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
第二次挥手
服务端收到这个FIN,他发回一个**ACK(确认),**确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。
服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
**第三次挥手**
服务端发送一个**FIN(结束)**到客户端,服务端关闭客户端的连接。
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
**第四次挥手**
客户端发送**ACK(确认)**报文确认,并将确认的序号+1,这样关闭完成。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
思考:那么为什么是4次挥手呢?
为了确保数据能够完成传输。
关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢.
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。
思考:客户端突然挂掉了怎么办?
正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到客户端的消息,就将计时器复位。超时时间通常设置为2小时。若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔75秒,还没有响应就认为客户端出了故障,因而终止该连接。
思考:为什么TIME_WAIT*2MSL才返回close状态
1)可靠的实现TCP全双工链接中止
虽然双方都同意终止了,挥手的四次都已经进行了,但是你要做好最坏的打算,网络连接是不可靠的,可能你发出去的ACK报文对方并没有收到,而对方因为处于LAST_ACK状态下的SOCKET因为超时而重新发一封FIN报文,所以这个等待的状态就是为了又接收一次FIN报文,然后重新发送一次ACK确认报文
2)防止已失效的连接请求报文段出现在本连接中
客户端在发送最后一个ACK确认报文后,再经过2MSL时间里,可以使所以在本次连接时间中产生的所有报文段全部失效,这样就可以是下一个新的连接中,不会出现这种旧的连接请求报文,防止某一个老的连接报文段被误以为是开始新的连接报文段
TCP流量控制
TCP流量控制主要是针对接收端的处理速度不如发送端发送速度快的问题,消除发送
方使接收方缓存溢出的可能性。
TCP流量控制主要使用滑动窗口协议,滑动窗口是接受数据端使用的窗口大小,用来告诉发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的。
这个窗口大小就是我们一次传输几个数据。对所有数据帧按顺序赋予编号,发送方在发送过程中始终保持着一个发送窗口,只有落在发送窗口内的帧才允许被发送;
同时接收方也维持着一个接收窗口,只有落在接收窗口内的帧才允许接收。这样通过调整发送方窗口和接收方窗口的大小可以实现流量控制。
TCP拥塞控制
流量控制是通过接收方来控制流量的一种方式;而拥塞控制则是通过发送方来控制流量的一种方式。
TCP发送方可能因为IP网络的拥塞而被遏制,TCP拥塞控制就是为了解决这个问题(注意和TCP流量控制的区别)。
TCP拥塞控制的几种方法:慢启动,拥塞避免,快重传和快恢复。
这里先理解一个概念: 拥塞窗口
拥塞窗口:发送方维持一个叫做拥塞窗口 cwnd的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态变化。
发送方的让自己的发送窗口=min(cwnd,接受端接收窗口大小)。说明: 发送方取拥塞窗口与滑动窗口的最小值作为发送的上限。
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
下面将讨论拥塞窗口cwnd的大小是怎么变化的。
1、慢开始
TCP在连接过程的三次握手后,就开始传送数据,并不是一下子就往网络中传输大量的数据。
如果网络出现问题,一下子传送大量的数据,可能导致路由器缓存空间耗尽,从而发生拥塞。现在的TCP规定了,在启动的时候会进入慢启动状态(低速传送),先传输小包的数据,随着时间的推移,逐步增加每次传送的数据量,进入高速传送状态,以避免产生网络拥塞的问题。
慢开始会引起性能损耗变大?
在一下高并发访问的网站,有时需要海量的碎片小文件的拷贝到另一个网站,完成网站的某些需求。如果在每次传输的时候为每个碎片的小文件建立一个单独的TCP传输,然而一开始就是处于慢启动的状态,这会导致原本来高速状态只需要一个包就能传输成功的小文件,在低速状态下需要2~3个包,从而使网络拷贝文件的时间基本上全部消耗都在网络传输的过程中
如何避免?
尽量把这些小文件都放在同一个TCP连接中传输掉,让一开始慢开始的低速阶段先传输几个小文件,而后在高速状态把其他小文件快速的传输完。用这样的方式来减少发包的数目,进而降低时间消耗。同样,实际上这种传输策略带来的性能提升的功劳不仅仅归于避免慢开始,事实上也避免了大量的3次握手和四次握手,这个对海量小文件传输的性能消耗
2、拥塞避免
慢开始并不是传输数据的增长速度变慢,而是在一开始先传输小包的数据,而后以指数级别的增长传输速度,为了防止cwnd增长过大引起网络拥塞,设置一个慢开始门限(ssthresh状态变量)
当cnwd<ssthresh,使用慢开始算法
当cnwd=ssthresh,既可使用慢开始算法,也可以使用拥塞避免算法
当cnwd>ssthresh,使用拥塞避免算法
拥塞避免算法:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
无论慢开始开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢启动门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢启动算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
强调:“拥塞避免”并非指完全能够避免了拥塞。利用以上的措施要完全避免网络拥塞还是不可能的。“拥塞避免”是说在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞
快速重传和快速恢复
快重传
1.快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
2.由于不需要等待设置的重传计时器到期,能尽早重传未被确认的报文段,能提高整个网络的吞吐量。
快速恢复
1.采用快恢复算法时,慢开始只在TCP连接建立时和网络出现超时时才使用。
2.当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。
3.考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。
TCP和UDP
UDP:无连接协议,也称透明协议,也位于传输层。
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
DOS攻击
DOS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击
故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提供正常的服务或资源访问,使目标系统服务系统停止响应甚至崩溃
常见的DOS攻击有计算机网络带宽攻击和连通性攻击。
带宽攻击指以极大的通信量冲击网络,使得所有可用网络资源都被消耗殆尽,最后导致合法的用户请求无法通过。
连通性攻击指用大量的连接请求冲击计算机,使得所有可用的操作系统资源都被消耗殆尽,最终计算机无法再处理合法用户的请求。
TCP洪水攻击(SYN Flood)
一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,常用假冒的IP或IP号段发来海量的请求连接的第一个握手包(SYN包),被攻击服务器回应第二个握手包(SYN+ACK包),因为对方是假冒IP,对方永远收不到包且不会回应第三个握手包。导致被攻击服务器保持大量SYN_RECV状态的“半连接”,并且会重试默认5次回应第二个握手包,塞满TCP等待连接队列,资源耗尽(CPU满负荷或内存不足),让正常的业务请求连接不进来。
最后
以上就是纯真中心为你收集整理的面试必问---TCP连接TCP连接TCP流量控制TCP拥塞控制快速重传和快速恢复TCP和UDPDOS攻击的全部内容,希望文章能够帮你解决面试必问---TCP连接TCP连接TCP流量控制TCP拥塞控制快速重传和快速恢复TCP和UDPDOS攻击所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复