TCP的三次握手编程
所谓三次握手(Three-way Handshake),是指创建一个TCP链接时,须要客户端和服务器总共发送3个包。服务器
确认号ack:期待收到对方下一个报文段的第一个数据字节的序号。cookie
确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效。网络
同步SYN:链接创建时用于同步序号。当SYN=1,ACK=0时表示:这是一个链接请求报文段。socket
若赞成链接,则在响应报文段中使得SYN=1,ACK=1。所以,SYN=1表示这是一个链接请求,或链接接受报文。tcp
终止FIN:用来释放一个链接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输链接。spa
第一次握手:
客户端发送一个TCP的SYN标志位置1的包指明客户打算链接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。blog
第二次握手:
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的ISN加1以.即X+1。队列
第三次握手:
客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.而且把服务器发来ACK的序号字段+1,放在肯定字段中发送给对方.而且在数据段放写ISN的+1进程
还要再发送一次确认是为了,防止已失效的链接请求报文段忽然又传到了B,于是产生错误。
已失效的报文段:正常状况下:A发出链接请求,但由于丢失了,故而不能收到B的确认。因而A从新发出请求,而后收到确认,创建链接,数据传输完毕后,释放链接,A发了2个,一个丢掉,一个到达,没有“已失效的报文段”。
可是,某种状况下,A的第一个在某个节点滞留了,延误到达,原本这是一个早已失效的报文段,可是在A发送第二个,而且获得B的回应,创建了链接之后,这个报文段居然到达了,因而B就认为,A又发送了一个新的请求,因而发送确认报文段,赞成创建链接,倘若没有三次的握手,那么这个链接就创建起来了(有一个请求和一个回应),此时,A收到B的确认,但A知道本身并无发送创建链接的请求,由于不会理睬B的这个确认,因而呢,A也不会发送任何数据,而B呢却觉得新的链接创建了起来,一直等待A发送数据给本身,此时B的资源就被白白浪费了。可是采用三次握手的话,A就不发送确认,那么B因为收不到确认,也就知道并无要求创建链接。
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攻击。
TCP的四次挥手
TCP的链接的拆除须要发送四个包,所以称为四次挥手(four-way handshake)。客户端或服务器都可主动发起挥手动做,在socket编程中,任何一方执行close()操做便可产生挥手操做。
第一次挥手:TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
第二次挥手:服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN同样,一个FIN将占用一个序号。
第三次挥手:服务器关闭客户端的链接,发送一个FIN给客户端。
第四次挥手:客户段发回ACK报文确认,并将确认序号设置为收到序号加1。
B收到链接释放报文段后就当即发送确认,而后就进入close-wait状态,此时TCP服务器进程就通知高层应用进程,于是从A到B的链接就释放了。此时是“半关闭”状态。即A不能够发送给B,可是B能够发送给A。
此时,若B没有数据报要发送给A了,其应用进程就通知TCP释放链接,而后发送给A链接释放报文段,并等待确认。
A发送确认后,进入time-wait,注意,此时TCP链接尚未释放掉,而后通过时间等待计时器设置的2MSL后,A才进入到close状态。
为何要等待呢?
①为了保证A发送的最后一个ACK报文段可以到达B。即最后这个确认报文段颇有可能丢失,那么B会超时重传,而后A再一次确认,同时启动2MSL计时器,如此下去。若是没有等待时间,发送完确认报文段就当即释放链接的话,B就没法重传了(链接已被释放,任何数据都不能出传了),于是也就收不到确认,就没法按照步骤进入CLOSE状态,即必须收到确认才能close。
②防止“已失效的链接请求报文段”出如今链接中。通过2MSL,那些在这个链接持续的时间内,产生的全部报文段就能够都从网络中消失。即在这个链接释放的过程当中会有一些无效的报文段滞留在楼阁结点,可是呢,通过2MSL这些无效报文段就确定能够发送到目的地,不会滞留在网络中。这样的话,在下一个链接中就不会出现上一个链接遗留下来的请求报文段了。