传输控制协议TCP简介
- 面向连接的、可靠的、基于字节流的传输层通信协议
- 将应用层的数据流分割成报文段发送给目标节点的TCP层
- 数据包都有序号,对方收到则发送ACK确认,未收到则重传
- 使用校验和来检验数据在传输过程中是否有误
TCP Flags
- ACK:确认序号标志,1表示确认号有效,0表示报文中不含确认信息,忽略确认号字段
- SYN:同步序号,用于建立连接过程 SYN=1,ACK=0表示数据段没有使用捎带的确认域,SYN=1,ACK=1则连接应答捎带一个确认域
- FIN:finish标志,用于释放连接,1表示发送方已经数据发送了,即关闭本方数据流
TCP三次握手
第一次握手:客户端发送请求连接报文(报文头:SYN标志=1,seq=x),即是SYN报文段,不能携带数据,但是消耗掉一个序号,同步已发送;
第二次握手:服务端发送确认报文(报文头:SYN标志=1,ACK标志=1,seq=初始化一个y,ack=x+1),不能携带数据,但是消耗掉一个序号,同步已收到;
第三次握手:客户端发送确认报文(ACK标志=1,seq=x+1,ack=y+1),可以携带数据,不携带就不消耗序号,连接已建立。
“握手”是为了建立连接,TCP三次握手的流程:
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接
第一次握手:建立连接时,客户端发送SYN包(seq=x)到服务器,并进入SYN_SEND状态,等待服务端确认;
第二次握手:服务器收到SYN包,必须确认客户端的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务端进入SYN_RECV状态;
第三次握手:客户端收到服务端的SYN+ACK包,向服务端发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务端进入ESTABLISHED状态,完成三次握手。
为什么需要三次握手才能建立连接
为了初始化Sequence Number的初始值,通信的双方要互相通知对方自己的初始化的Sequence Number,这个序号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上传输问题而乱序,即TCP会用这个序号来拼接数据,需要第三次握手,告知服务端客户端已经接收到了你的初始化的Sequence Number
首次握手的隐患—SYN超时
问题起因
Server收到Client的SYN包,回复了SYN+ACK后,Client掉线,Sever端没有收到Client端发送回来的ACK确认, 这个连接即没有成功也没有失败。如果Server在一定时间内没有收到客户端的回执,它就会重发SYN+ACK,在Linux下默认重试5次,重试间隔时间从1秒开始每次翻倍,在第五次发去后还要等32秒,才能被判定超时,Linux就默认等待63秒,TCP才会断开这个连接。这可能会引起SYN Flood攻击,SYN Flood攻击会把服务端的SYN连接队列耗尽,正常连接请求不能处理。
针对SYN Flood的防护措施
SYN队列满了,TCP会通过源地址端口和目标地址和时间戳生成tcp_syncookie参数,将其回发
若正常连接则Client会回发SYN Cookie,直接建立连接。
建立连接后,Client出现故障
TCP提供保活机制
- 向对方发送保活探测报文,如果未收到响应继续发送
- 尝试次数达到保活探测数仍未收到响应则中断连接
TCP和UDP区别
- 面向连接VS无连接,tcp有三次握手的连接过程,udp无连接,适合消息的多播发布,从单个点向多个点传输信息
- 可靠性,tcp可靠(通过握手,确认,重传机制保证可靠性),udp可能会丢失,不知道有没有被接收
- 有序性,tcp利用序列号保证消息的顺序交互
- 速度,tcp速度慢,因为要创建连接,保证消息的可靠性和有序性,udp更适合对速度比较敏感的应用,比如在线视频媒体,电视广播,多人在线游戏
- 量级,tcp重量级,体现在元数据的头,tcp是20个字节,udp是8个字节