TCP,UDP,HTTP
TCP
- 面向连接的、可靠的、基于字节流的传输层通信协议
- 将应用层的数据流分割成报文段并发送给目标节点的TCP层
- 数据包都有序号,对方收到则发送ACK确认,未收到则重传
- 使用校验和来检验数据在传输过程中是否有误
TCPflags
- URG:紧急指针标志
- ACK:确认序号标志
- PSH:push标志
- SYN:建立连接标志
- FIN:释放连接标志
- RST:重置连接标志
三次握手
在TCP协议中,TCP协议提供可靠的服务,采用三次握手建立一个连接
- 第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认
- 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=j+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
为什么三次握手才能建立连接
- 为了要初始化Sequence Number的初始值,通信的双方要互相通知对方自己的SYN初始值,作为以后的数据通讯的序号,来保证应用层数据不会因为网络上的传输问题而乱序,即TCP会用这个数据来拼接数据
首次握手隐患:SYN超时问题
- 起因:
Server收到Client的SYN,在回复SYN+ACK的时候未收到ACK确认
Server不断重发直至超时,在linux系统中是63秒才断开连接
-
针对SYN-Flood的防护措施
SYN队列满后,通过tcp_syncookies参数回发SYN Cookie
若为正常连接则Client会回发SYN Cookie,直接建立连接
-
建立连接后Client发生故障怎么办——保活机制:
向对方发送保活探测报文,如果未收到响应则继续发送
尝试次数达到保活探测数仍未收到响应,则断开连接
四次挥手
-
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态
-
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到的序号加一(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
-
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态
-
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到的序号加一,Server进入CLOSED状态,完成四次挥手
为什么会有TIME_WAIT状态
- 确保有足够的时间让被动关闭的一方收到ACK
- 避免新旧连接混淆
为什么需要四次挥手才能断开
- 因为全双工,发送方和接收方都需要ACK报文和FIN报文
服务器出现大量CLOSE_WAIT状态的原因
- 对方关闭socket连接,但接收方忙于读或写,没有及时关闭连接,通常是因为程序中有BUG
解决方式:
- 检查代码,特别是释放资源的代码
- 检查配置,特别是处理请求的线程配置 (线程池的配置)
检查配置,特别是处理请求的线程配置 线程池的配置
UDP
UDP特点
- 面向非连接
- 不维护连接状态,支持同时向多个客户端传输相同的消息
- 数据包报头只有八个字节,额外数据开销较小
- 吞吐量只限制于数据生成速率、传输速率以及机器性能
- 尽最大努力交付,不保证可靠交付,不需要维持复杂的连接状态
- 面向报文,不对应用程序提交的报文信息进行拆分或者合并
TCP和UDP的区别
- 面向连接和无连接
- 可靠性
- 有序性
- 速度
- 量级 体现在头大小(20,8)
TCP的滑动窗口:
- 用滑动窗口做流量控制和乱序重排
RTT 和 RTO:
- RTT:发送一个数据包,到收到相对应的ACK所需要的时间
- RTO:重传时间间隔
保证TCP的可靠性
保证TCP的流控特性
HTTP
HTTP协议的特点
-
支持客户/服务器模式
-
简单快速
-
灵活 类型灵活 Content Type标记
-
无连接 下层实现对上层透明
-
无状态 协议对事物处理没有记忆能力,若需要之前的数据,则需要进行重传
键入URL按下回车后经历的流程
- DNS解析
- TCP连接
- 发送HTTP请求
- 处理请求并返回HTTP响应
- 浏览器渲染页面
- 连接结束
HTTP状态码
- 1**:指示信息—表示请求已接受,继续处理
- 2**:成功—表示请求已被成功接收、理解、接受
- 3**: 重定向—要完成请求需要进行更进一步的操作
- 4**:客户端错误—请求有语法错误或请求无法实现
- 5**:服务器端错误—服务器未能实现合法的请求
GET和POST的区别
- HTTP层面:get将请求信息放在URL中,post放在报文体中
- 数据库层面:get符合幂等性(对数据库的一次和多次操作的结果一致)和安全性,post不符合
- 其他层面:get请求能够被缓存、被储存,post不可以