http://www.cnblogs.com/zmlctt/p/3690998.html
三次握手为建立连接,四次挥手为终止连接
一、Tcp报文格式
TCP/IP协议的详细信息参看《TCP/IP协议详解》三卷本。下面是TCP报文格式图:
上图中有几个字段需要重点介绍下:
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
二、三次握手
目的:连接服务器制定端口,建立Tcp连接,同步连接双发的序列号和确认好并交换Tcp窗口大小信息。在socket编码中,客户端执行connect()时,触发三次握手。
第一次握手:客户端发送一个SYN标志位1的包,表明客户打算连接服务器的端口,以及初始序号X,保存在包头的序列号字段里。
(客户端发起一个建立连接的请求SYN=1)
Client进入SYN_SENT状态,等待Server确认
第二次握手:
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1,将确认序号(Acknowledgement Number)设置为客户的ISN加1,即X+1。
(服务器收到客户端发送的建立连接请求后,发送确认包给服务器表示我收到你的请求,且我同意建立连接 。)Server进入SYN_RCVD状态
第三次握手:
客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段上的ISN+1
(客户端确认ack是否为初始序号X+1,ACK是否为1,如果正确则建立连接成功)Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
SYN攻击:是指在三次握手的过程中,完成两次握手后的状态称为半连接状态,
此时Server处于SYN_RCVD状态,此时发生攻击是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
#netstat -nap | grep SYN_RECV
一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.
但是不能完全防范syn攻击。
但是不能完全防范syn攻击。
三、四次挥手
TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
由于Tcp是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方没有数据发送任务后,发送一个FIN来终止该方的连接,此后该方不可在发送数据给另一方,但此方仍可以接收数据,因为另一方并未终止连接。当另一方也发送FIN后,TCP连接才断开。首先进行关闭的一方式主动关闭,另一方执行被动关闭。
第一次挥手:
Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态
。
第二次挥手:
Server收到FIN后
,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
。
。
第三次挥手:
Server发送一个FIN
,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态
。
第四次挥手:
Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1
,
Server进入CLOSED状态,
完成四次挥手。
四、问题题
1、为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端的LISTEN状态下的SOCKET,当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
(建立连接时,第二次握手服务器把ACK应答报文和SYN同步报文放在一个包里面发送,但第二次挥手和第三次挥手分开是因为断开是双方分别断开,一方断开另一方,仍然可以给他发送数据的,所以需要先发送确认收到你要断开的报文,再在我方数据发送完毕后发送FIN报文通知断开连接。)
2、TCP与UDP的区别是什么
(1)TCP协议是
有连接的,有链接的意思是开始传输实际数据之前TCP的客户端和服务器端必须通过三次握手建立连接,会话结束之后也要结束连接,而UDP是无连接的。
(2)TCP协议保证数据
按序发送,按序接收,提供超时重传来保证可靠性,但是UDP不保证按序到达,甚至不保证到达,只是努力交付,即便是按序发送的序列,也不保证按序送到。
(3)TCP所需资源比UDP多,TCP收不需要20个字节,UDP首部只需要8个字节。
(4)TCP有流量控制和拥塞控制,UDP没有,网络拥堵不会影响发送端的发送速率,
(5)TCP是
一对一的连接,而UDP可以支持一对一,一对多,多对多的通信。
(6)TCP面向的是
字节流的服务,UDP面向的是
报文的服务。