博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP的三次握手和四次挥手
阅读量:6084 次
发布时间:2019-06-20

本文共 2910 字,大约阅读时间需要 9 分钟。

hot3.png

 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)状态。

此时,客户端已经没有数据要发送了,但是服务器端可能还有数据要发送,且客户端依然可以接受服务端发送的数据,这时的TCP连接处于半关闭状态。(补充:断开TCP连接 即 客户端关闭发送数据的通道 并且 服务端关闭发送数据的通道。)

第三次挥手: 应用进程通知服务器进程释放连接后,服务器进程发出连接释放报文段,报文段首部中 确认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的确 认状态,相互等待造成死锁。

*>为什么连接的时候是三次握手,关闭的时候却是四次握手?

建立连接时:当Server端收到Client端的SYN连接请求报文后,Server端可以直接发送SYN+ACK报文,其中ACK报文是用来应答的,SYN报文是用来同步的。

关闭连接时:当Server端收到Client端的FIN报文后,Server端很可能不会立即关闭SOCKET,而是先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了,但是我(可能)还有数据要发送",当Server端所有的报文都发送完了,Server端才会发送FIN报文,即Server端通知Client端的过程中需要挥两次手,故在关闭连接的时候总共需要四次挥手。

*>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攻击

转载于:https://my.oschina.net/u/1399755/blog/1815947

你可能感兴趣的文章
python 注册
查看>>
转 python数据类型详解
查看>>
Thread 初学(二)——线程同步
查看>>
文件管理器
查看>>
12招jQuery常用技巧
查看>>
subline 快捷键与功能解释
查看>>
Ubuntu+apache安装redmin
查看>>
使用mysqldump迁移数据
查看>>
路径问题
查看>>
shiro 静态页面资源不显示 解决方案
查看>>
[转] PostgreSQL学习手册(数据表)
查看>>
HDU-1159 Common Subsequence(动态规划2)
查看>>
spl_autoload_register更改框架文件引用模式
查看>>
diff文件生成小记
查看>>
RN中有两种方式使用全局变量
查看>>
处理 Oracle SQL in 超过1000 的解决方案
查看>>
maven项目在eclipse的library中没有Maven Dependencies
查看>>
RN初始化环境快速配置
查看>>
10.Lambda表达式入门
查看>>
maven jar 导入本地仓库
查看>>