TCP有6种标示:SYN(创建联机) ACK(确认) PSH(传送) FIN(结束) RST(重置) URG(紧急) html
1、TCP三次握手
第一次握手服务器
客户端向服务器发出链接请求报文,这时报文首部中的同部位SYN=1,同时随机生成初始序列号 seq=x,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状cookie
态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但须要消耗掉一个序号。这个三次握手中的开始。表示客户端想要和服务端创建链接。网络
第二次握手tcp
TCP服务器收到请求报文后,若是赞成链接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为本身随机初始化一个序列号 seq=y,此spa
时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,可是一样要消耗一个序号。这个报文带有SYN(创建链接)和ACK(确认)标志,询问客户端设计
是否准备好。server
第三次握手htm
TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,此时,TCP链接创建,客户端进入ESTABLISHED(已创建链接)状态。blog
TCP规定,ACK报文段能够携带数据,可是若是不携带数据则不消耗序号。这里客户端表示我已经准备好。
思考:为何要三次握手呢,有人说两次握手就行了
举例:已失效的链接请求报文段。
client发送了第一个链接的请求报文,可是因为网络很差,这个请求没有当即到达服务端,而是在某个网络节点中滞留了,直到某个时间才到达server,原本这已是一个失效
的报文,可是server端接收到这个请求报文后,仍是会想client发出确认的报文,表示赞成链接。假如不采用三次握手,那么只要server发出确认,新的创建就链接了,但其实这个
请求是失效的请求,client是不会理睬server的确认信息,也不会向服务端发送确认的请求,可是server认为新的链接已经创建起来了,并一直等待client发来数据,这样,server的
不少资源就没白白浪费掉了,采用三次握手就是为了防止这种状况的发生,server会由于收不到确认的报文,就知道client并无创建链接。这就是三次握手的做用。
2、TCP数据的传输过程
创建链接后,两台主机就能够相互传输数据了。以下图所示:
1)主机A初始seq为1200,滑动窗体为100,向主机B传递数据的过程。
2)假设主机B在彻底成功接收数据的基础上,那么主机B为了确认这一点,向主机A发送 ACK 包,并将 Ack 号设置为 1301。所以按以下的公式确认 Ack 号:
Ack号 = Seq号 + 传递的字节数 + 1 (这是在彻底接受成功的状况下)
3)主机A得到B传来的ack(1301)后,开始发送seq为1301,滑动窗体为100的数据。
......
与三次握手协议相同,最后加 1 是为了告诉对方要传递的 Seq 号。上面说了,主机B彻底成功接收A发来的数据才是这样的,若是存在丢包该如何。
下面分析传输过程当中数据包丢失的状况,以下图所示:
上图表示经过 Seq 1301 数据包向主机B传递100字节的数据,但中间发生了错误,主机B未收到。通过一段时间后,主机A仍未收到对于 Seq 1301 的ACK确认,所以尝试
重传数据。为了完成数据包的重传,TCP套接字每次发送数据包时都会启动定时器,若是在必定时间内没有收到目标机器传回的 ACK 包,那么定时器超时,数据包会重传。
上面也只是一种可能,好比数据1250丢失,那么Ack返回的就是1250,具体的能够详细看下博客:【TCP协议】(1)---TCP协议详解,这里面滑动窗口有说明。
3、TCP的四次挥手
第一次挥手
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秒,
尚未响应就认为客户端出了故障,于是终止该链接。
4、SYN(洪水)攻击
背景
初始化链接的 SYN 超时问题Client发送SYN包给Server后挂了,Server回给Client的SYN-ACK一直没收到Client的ACK确认,这个时候这个链接既没创建起来,也不能算
失败。这就须要一个超时时间让Server将这个链接断开,不然这个链接就会一直占用Server的SYN链接队列中的一个位置,大量这样的链接就会将Server的SYN链接队列耗尽,
让正常的链接没法获得处理。
目前,Linux下默认会进行5次重发SYN-ACK包,重试的间隔时间从1s开始,下次的重试间隔时间是前一次的双倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第
5次发出后还要等32s都知道第5次也超时了,因此,总共须要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才会把断开这个链接。因为,SYN超时须要63秒,那么就给攻击者一
个攻击服务器的机会,攻击者在短期内发送大量的SYN包给Server(俗称SYN flood攻击),用于耗尽Server的SYN队列。
什么是 SYN 攻击
SYN 攻击指的是,攻击客户端在短期内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。因为源地址是不存在的,服务器
须要不断的重发直至超时,这些伪造的SYN包将长时间占用未链接队列,正常的SYN请求被丢弃,致使目标系统运行缓慢,严重者会引发网络堵塞甚至系统瘫痪。SYN 攻击是一
种典型的 DoS攻击。
如何检测 SYN 攻击?
检测 SYN 攻击很是的方便,当你在服务器上看到大量的半链接状态时,特别是源IP地址是随机的,基本上能够判定这是一次SYN攻击。在 Linux/Unix 上可使用系统自带的
netstats 命令来检测 SYN 攻击。
如何防护 SYN 攻击?
SYN攻击不能彻底被阻止,除非将TCP协议从新设计。咱们所作的是尽量的减轻SYN攻击的危害,常见的防护 SYN 攻击的方法有以下几种:
缩短超时(SYN Timeout)
时间增长最大半链接数
过滤网关防御SYN
cookies技术
4、TCP和UDP的区别
我这里简单列举几个,由于我尚未研究UDP这个协议。
一、基于链接与无链接;UDP是无链接的,即发送数据以前不须要创建链接
二、TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。也就是说,经过TCP链接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付
,即不保证可靠交付Tcp经过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还能够对次序乱掉的分包进行顺序控制。
三、UDP具备较好的实时性,工做效率比TCP高,适用于对高速传输和实时性有较高的通讯或广播通讯。
四、每一条TCP链接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通讯。
五、TCP对系统资源要求较多,UDP对系统资源要求较少。