TCP/IP
OSI的“实现”:TCP/IP
TCP的三次握手
传输控制协议TCP协议
- 面向连接的、可靠的、基于字节流的传输层通信协议
- 将应用层的数据刘分割成报文段并发送给目标节点的TCP层
- 数据包都有序号,对方收到则发送ACK确认,未收到则重传
- 使用校验和来检验数据再传输过程中是否有错误
TCP 报文头
- Sequence Number:该报文的第一个字节的序号
- Acknowledgement Number:期待发送方发送的下一个报文段的第一个字节的序号,即发送发报文的Sequence Number
TCP Flags
- URG:紧急指针标志
- ACK:确认序号标志
- PSH:push标志
- RST:重置连接标志
- SYN:同步序号,用于建立连接过程
- FIN:finish标志,用于释放连接
TCP的三次握手
“握手”是为了建立连接,TCP三次握手的流程图如下:
- 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接
- 第一次握手,建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SNED状态,等待服务器确认
- 第二次握手:服务器收到SYN 包,必须确认客户的SYN(ack=j+1),同时自己也发送又给SYN包(syn=k),即SYN+ACK包,此时服务进入SYN_RECV状态
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
为什么需要三次握手才能建立气连接
首次握手的隐患–SYN超时
问题起因分析
- Server收到Client的SYN,回复SYN-ACK的时候未收到ACK确认
- Server不断重试直至超时,Linux默认等待63秒才断开连接
针对SYN Flood的防护措施
- SYN队列满后,通过tcp_syncookies参数回发SYN Cookie
- 若未正常连接则Client会回发SYN Cookie,直接建立连接
建立连接后,Client出现故障怎么办
保活机制
- 向对方发送保活探测报文,如果未收到响应则继续发送
- 尝试次数到达保活探测数仍未收到响应则中断连接
TCP的四次挥手
“挥手”是为了终止连接,TCP四次挥手的流程图如下:
- 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进入CLISED状态,完成四次挥手
为什么会有TIME_WAIT状态
- 确保有足够的时间让对方收到ACK包
- 避免新旧连接混淆(路由器会缓存一些包)
为什么需要四次挥手才能断开连接
- 因为全双工,发送方和接收方都需要FIN报文和ACK报文
服务器出现大量CLOSE_WAIT状态的原因
- 对方关闭socket连接,我方忙于读或写,没有及时关闭连接
- 检查代码,特别是释放资源的代码
- 检查配置,特别是处理请求的线程配置
TCP和UDP的区别
UDP简介
- UDP报文结构
- UDP的特点
- 面向非连接
- 不维护连接状态,支持同时向多个客户传输相同的消息
- 数据包报头只有8个字节,额外开销较小
- 吞吐量只受限于数据生成速率,传输速率以及机器性能
- 尽最大努力交付,不保证可靠交付,不需要维持复杂的连接状态表
- 面向报文,不对应用程序提交的报文信息进行拆分或者合并
TCP和UDP的区别
TCP的滑窗
RTT和RTO
- RTT:发送一个数据包到收到对应的ACK,所花费的时间
- RTO:重传时间间隔
TCP使用滑动窗口做流量控制与乱序重排
如果每次发送一个数据段并且接收收到ACK以后再发送下一个数据段的方式效率太低,所以采取一次发送多个数据段。
- 滑动窗口的作用
- 数据段中 的Window字段:
- 接收方用于通知发送方,自己还有多少缓冲区可以接收数据。
窗口数据的计算过程
发送方
- LastByteAcked: 连续收到接收端的ACK回执的位置(此位置之前的数据都已经收到接收方的ACK)
- lastByteSent:表示发送方已经将数据发送出去了,但是还没有收到接收方的ACK回应
- LastByteWritten:表示上层应用已写完的最后一个位置(当前程序已经准备好的数据)
接收方
- LastByteRead:上层应用已经读完的数据最后一个位置(处理并回执了的最后一个位置)
- NextByteExpected:指向收到的连续最大的sequence的位置,但是并没有发送绘制
- LastByteRcvd:已收到的最后一个序号位置。在LastByteRcvd和NextByteExpected之间有一些包没有到达。
窗口大小 - AdvertisedWindow:接收方还能接收的数据量,并将这个值告知发送端。
- EffectiveWindow:发送方 窗口内剩余可发送数据大小
TCP会话的发送方
发送方的缓存可以分为4类
- 已经发送得到回应的
- 已经发送还没收到回应的(窗口部分)
- 未发送但是允许发送的 (窗口部分)
- 未发送但是达到了window的大小,不允许发送的
窗口滑动的原理
- 当收到接收方发送的新的ACK对于发送窗口中后续字节连续被确认时,窗口就会进行滑动
TCP会话的接收方
接收方缓存可以分为3类
- 接收并发送回执
- 没有接收,但是允许发送端发送(准备接收状态)
- 未接受,并且不能接收的状态(达到了窗口的阈值)
注意:
1. ACK由TCP栈恢复,没有应用延迟,不存在,已接受,没有绘制的状态
2. 接收方的窗口滑动原理和发送方的窗口滑动原理一致
HTTP简介
超文本传输协议HTTP主要特点
- 支持客户端/服务器模式
- 简单快速
客户端向服务器发送请求时,只需要传送请求方法和路径 - 灵活
可以传输任意类型的数据对象(类型由contentType标记) - 无连接
限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答之后即断开连接。HTTP1.1采用长连接,即服务器需要等待一定时间后才断开连接,以保证连接特性。虽然keepalive使用长连接优化效率,但是这属于Http请求之外的,在每个独立的http请求之中,无法知道是否处于长连接状态,长连接可以理解为下层连接对长层透明。 - 无状态
协议对事物处理没有记忆能力,如果后续处理需要前面的信息,必须要进行重传。
HTTP请求结构
HTTP响应报文
请求/响应步骤
- 客户端连接到Web服务器:
建立TCP套接字连接 - 发送HTTP请求:
通过TCP套接字向Web服务器发送一个文本的请求报文 - 服务器接收请求并返回HTTP响应:
服务器解析该请求,并定位资源,服务器将资源副本写到TCP套接字,由客户端读取 - 释放TCP连接:
连接方式为close,服务器主动关闭连接,客户端被动关闭连接; keepalive,该连接保持一段时间。 - 客户端浏览器解析HTML内容:
客户端浏览器首先查看状态行,是否返回成功,然后解析每一个响应头,响应头告知一下为若干字节的html文档和文档的字符集。客户端读取响应数据的html,根据html的语法对其进行格式化,并在浏览器窗口中显示
在浏览器地址栏键入URL,按下回车之后经历的流程
- DNS解析:
逐层查询DNS服务器缓存,解析URL中的域名所对应的IP地址,DNS由近到远依次时浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,域名服务器缓存,顶级域名服务器缓存 ,从哪个缓存中找到IP后直接返回,不再查询后面的缓存。 - TCP连接
三次握手 - 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
四次挥手
HTTP的状态码
- 200 OK:正常返回信息
- 400 Bad Request: 客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized:请求未经授权,这个状态码必须和WWW-Authenticate报头域一起使用
- 403 Forbiden:服务器收到请求,但是拒绝提供服务
- 404 Not Found:请求资源不存在,eg,输入了错误的url
- 500 Internal Server Error :服务器发生不可预期的错误
- 503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常
GET请求和POST请求的区别
- HTTP报文层面:GET将请求信息放在URL,POST放在报文体中
- 数据库层面:GET符合幂等性和安全性,POST不符合
- 其他层面:GET可以被缓存,被存储,而POST不行。绝大多数的GET请求都被CDN缓存了。大大减少Web服务器的负担。
Cookie和Session的区别
Cookie简介
- 是由服务器发给客户端的特殊信息,以纯文本的形式存放在客户端
- 客户端再次请求的时候,会把Cookie回发
- 服务器接收到后,会解析Cookie生成与客户端相对应的内容(eg,记住我)
Cookie 的设置以及发送过程
Session简介
- 服务器端的机制,在服务器上保存的信息
- 解析客户端请求并操作Session id,按需保存状态信息
Session的实现方式
Session和Cookie的区别
- Cookie数据存放在客户浏览器上,Session数据放在服务器上
- Session相对于Cookie更安全
- 若考虑减轻服务器负担,应当使用Cookie
HTTP和HTTPS的区别
我们把添加了加密及认证机制的 HTTP 称为 HTTPS(HTTP Secure) 。
SSL(Security Sockets Layer,安全套接层)
- 为网络通信提供安全及数据完整性的一种安全协议
- 是操作系统对外的API,SSL3.0后更名为TLS
- 采用身份验证和数据加密保证网络通信的安全和数据的完整
加密的方式
- 对称加密:加密和解密都使用同一个密钥
- 非对称密钥:加密使用的密钥和解密使用的密钥是不相同的
- 哈希算法:将任意长度的信息转换为固定长度的值,算法不可逆
- 数字签名:整明某个消息或者文件是某人发出/认同的
HTTPS数据传输流程
- 浏览器将支持的加密算法信息发送给服务器
- 服务器选择一套浏览器支持的加密算法,以证书的形式回发给浏览器(证书上有公钥和CA机构对公钥的数字的数字签名)
- 浏览器验证证书的合法性,并结合证书的公钥将浏览器生成的密码(后续使用的共享密钥)加密,利用生成的密码(后续的密钥)和加密后的消息的hash值生成消息认证码(MAC),最终将信息发送给服务器。
- 服务器使用私钥解密信息,并利用解密得到的密码(后续使用的共享密钥)验证消息认证码(MAC),最后加密相应消息回发浏览器
- 浏览器解密相应消息,并对消息进行验证,之后进行加密交换数据(共享密钥)
HTTP和HTTPS的区别
- HTTPS需要到CA申请证书,HTTP不需要
- HTTPS密文传输,HTTP明文传输
- 连接方式不同,HTTP默认使用443端口,HTTP使用80端口
- HTTP=HTTP + 加密 + 认证 + 完整性保护,较HTTP安全
Socket简介
|