TCP(Transmission Control Protocol) 传输控制协议服务器
TCP是主机对主机层的传输控制协议,提供可靠的链接服务,采用三次握手确认创建一个链接:cookie
位码即tcp标志位,有6种标示:SYN(synchronous创建联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)网络
Sequence number(顺序号码) Acknowledge number(确认号码)并发
下面详细介绍几个TCP标志位:
tcp
ACK : TCP协议规定,只有ACK=1时有效,也规定链接创建后全部发送的报文的ACK必须为1ide
SYN(SYNchronization) : 在链接创建时用来同步序号。当SYN=1而ACK=0时,代表这是一个链接请求报文。对方若赞成创建链接,则应在响应报文中使SYN=1和ACK=1. 所以, SYN置1就表示这是一个链接请求或链接接受报文。spa
FIN (finis):即完,终结的意思, 用来释放一个链接。当 FIN = 1 时,代表此报文段的发送方的数据已经发送完毕,并要求释放链接。3d
TCP创建链接:orm
首先Client端发送链接请求报文,Server段接受链接后回复ACK报文,并为此次链接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP链接就创建了。blog
注意:中断链接端能够是Client端,也能够是Server端。
假设Client端发起中断链接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",可是若是你还有数据没有发送完成,则没必要急着关闭Socket,能够继续发送数据。因此你先发送ACK,"告诉Client端,你的请求我收到了,可是我还没准备好,请继续你等个人消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端肯定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭链接了"。Client端收到FIN报文后,"就知道能够关闭链接了,可是他仍是不相信网络,怕Server端不知道要关闭,因此发送ACK后进入TIME_WAIT状态,若是Server端没有收到ACK则能够重传。“,Server端收到ACK后,"就知道能够断开链接了"。Client端等待了2MSL后依然没有收到回复,则证实Server端已正常关闭,那好,我Client端也能够关闭链接了。TCP链接就这样关闭了!
注意: 在TIME_WAIT状态中,若是TCP client端最后一次发送的ACK丢失了,它将从新发送。TIME_WAIT状态中所须要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待以后链接正式关闭,而且全部的资源(包括端口号)都被释放。
答疑时间:
为何不能用两次握手进行链接?
咱们知道,三次握手完成两个重要的功能,既要双方作好发送数据的准备工做(双方都知道彼此已准备好),也要容许双方就初始序列号进行协商,这个序列号在握手过程当中被发送和确认。
如今把三次握手改为仅须要两次握手,死锁是可能发生的。做为例子,考虑计算机S和C之间的通讯,假定C给S发送一个链接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为链接已经成功地创建了,能够开始发送数据分组。但是,C在S的应答分组在传输中被丢失的状况下,将不知道S 是否已准备好,不知道S创建什么样的序列号,C甚至怀疑S是否收到本身的链接请求分组。在这种状况下,C认为链接还未创建成功,将忽略S发来的任何数据分 组,只等待链接确认应答分组。而S在发出的分组超时后,重复发送一样的分组。这样就造成了死锁。
关于SYN***:
在三次握手过程当中,服务器发送SYN-ACK以后,收到客户端的ACK以前的TCP链接称为半链接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.
Syn***就是 ***客户端 在短期内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,因为源地址是不存在的,服务器须要不断的重发直 至超时,这些伪造的SYN包将长时间占用未链接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引发网络堵塞甚至系统瘫痪。
Syn***是一个典型的DDOS***。检测SYN***很是的方便,当你在服务器上看到大量的半链接状态时,特别是源IP地址是随机的,基本上能够判定这是一次SYN***.在Linux下能够以下命令检测是否被Syn***
netstat -n -p TCP | grep SYN_RECV
通常较新的TCP/IP协议栈都对这一过程进行修正来防范Syn***,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增长最大半链接和缩短超时时间等.
可是不能彻底防范syn***。
为何链接的时候是三次握手,关闭的时候倒是四次握手?
答:由于当Server端收到Client端的SYN链接请求报文后,能够直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同 步的。可是关闭链接时,当Server端收到FIN报文时,极可能并不会当即关闭SOCKET,因此只能先回复一个ACK报文,告诉Client端,"你 发的FIN报文我收到了"。只有等到我Server端全部的报文都发送完了,我才能发送FIN报文,所以不能一块儿发送。故须要四步握手。
为何TIME_WAIT状态须要通过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,咱们能够直接进入CLOSE状态了,可是咱们必须假象网络是不可靠的,有能够最后一个ACK丢失。因此TIME_WAIT状态就是用来重发可能丢失的ACK报文。