首页 > 代码库 > TCP的三次握手和四次挥手

TCP的三次握手和四次挥手



TCP三次握手:
---------------------------------

是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。

三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息,在socket编程中,客户端执行connect()时。将触发三次握手。

序号(seq):本报文段所发送的数据的第一个字节的序号
确认号(ack):是期望收到对方下一个报文段的第一个数据字节的序号;若确认号为x,则到序号x-1为止(包括x-1)的所有数据都已正确收到
确认(ACK):仅当 ACK=1 时,确认号字段才有效,当 ACK=0时,确认号无效;TCP规定:在连接建立后所有传送的报文都必须把ACK置1
同步(SYN):当 SYN=1 而 ACK=0 时,表明这是一个连接请求报文段,若对方同意建立连接,则应在响应的报文中使用 SYN=1 和 ACK=1 ;SYN=1 就表示这是一个连接请求或连接接受报文。
终止(FIN):用来释放一个连接。当 FIN=1 时,表明此报文的发送方的数据已发送完毕,并要求释放运输连接。

TCP规定:
*在连接建立后所有传送的报文都必须把ACK置1。
*SYN 报文段、FIN 报文段不能携带数据,但要消耗掉一个序号。
*ACK 报文段可以携带数据,但如果不携带数据则不消耗序号。


一个完整的三次握手也就是:请求--应答--再次确认

第一次握手:
客户端进程向服务器进程发出连接请求报文段,报文段首部中 (初始)序号seq=x,同步SYN=1,这时客户端进程进入SYN-SENT(同步已发送)状态。

第二次握手:
服务器进程收到连接请求报文段后,若同意建立连接,则向客户端进程发送响应报文段,报文段首部中 同步SYN=1,确认ACK=1,确认号ack=x+1(注:确认号ack=客户端进程的seq+1),(初始)序号seq=y,这时服务器进程进入SYN-RCVD(同步收到)状态。

第三次握手:
客户端进程收到服务器进程的响应报文段后,还要想服务器进程发出确认报文段,报文段的首部中 同步SYN=0,确认ACK=1,确认号ack=y+1,序号seq=x+1,这时TCP连接已建立,客户端进程和服务器进程都进入ESTABLISHED(已建立连接)

完成三次握手,主机A与主机B开始传送数据

注:序号seq等于前面已传送过的数据的最后一个字节的序号+1,在第一次握手中,seq=x,SYN=1(占一个序号位,即把 x 这个序号位给占了,所以下一次传送的序号应该从x+1开始,挥手时的FIN也同理)

---------------------------------
TCP 四次挥手
---------------------------------
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作

第一次挥手:
客户端进程向服务器段进程发出连接释放报文段,并停止再发送数据,主动关闭TCP连接,报文段首部中 终止FIN=1,序号seq=u,此时客户端进程进入FIN-WAIT-1(终止等待1)状态

第二次挥手:
服务器进程收到客户端进程的连接释放报文段后,向客户端进程发送确认报文段,报文段首部中 确认ACK=1,确认号ack=u+1,序号seq=v,此时服务器进程就进入CLOSE-WAIT(关闭等待)状态,并通知高层应用进程。
客户端进程收到服务器进程的确认报文段后,客户端进程就进入FIN-WAIT-2(终止等待2)状态。

第三次挥手:
应用进程通知服务器进程释放连接后,服务器进程发出连接释放报文段,报文段首部中 确认ACK=1,FIN=1 ,序号seq=w(在半关闭状态时服务器进程可能又发送了一些数据),确认号ack=u+1,此时服务器进程进入LAST-ACK(最后确定)状态。

第四次挥手:
客户端进程收到服务器进程的连接释放报文段后,向服务器进程发送确定报文段,报文段段首部中 确认ACK=1,序号seq=u+1,确认号ack=w+1,此时客户端进程进入到TIME-WAIT(时间等待)状态,等到等待时间过后,二者才都进入到CLOSED(关闭)状态


*>三次握手的目的:
1 要双方做好发送数据的准备工作(双方都知道彼此已经准备好)
2 要双方就初始序列号进行协商和确定

*>三次握手改为两次握手会产生死锁
如果采用两次握手,有如下情况:A,B两台主机,A发送连接请求,B给予确认,则认为连接建立,如果B的确认包在传输的过程中丢失,对A而言将一直处于等待B的确认状态,而B认为建立以成功,可以传输数据,B传给A的数据,A将不予接受,从而B处于等待A的确   认状态,相互等待造成死锁。


*>SYN攻击
在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于SYN-RCVD状态.当收到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的三次握手和四次挥手