日常梳理-网络协议
文章目录1.TCP1.1 TCP 长连接特点TCP 长连接中单工和双工模式主要取决于应用程序的设计1.2 单工/双工通讯协议单工通讯模式双工通讯模式2.HTTP2.1 网络分层模型1、OSI七层模型2、TCP/IP 四层模型2.2 请求方法标准请求方法安全与幂等2.3 报文结构1、请求/响应报文结构2、请求行3、状态行-服务器响应的状态4、头部字段2.4 HTTP的实体数据1MIME type2Encoding type2.5 HTTP的长连接与短连接1HTTP/1.1 如何实现长连接2.6 HTTP的重定向和跳转2.7 HTTP的cookie机制2.8 HTTP的缓存控制2.9 状态码4.Webclient使用1常见Http异常2) WebClient 里最关键的异常对应表2使用实例2.REST概念资源Resources表现层Representation状态转化State Transfer5. URI与URL的区别URI常用格式URI包含动词URI中加入版本号感谢极客时间-透视HTTP协议罗剑锋老师~1.TCP1.1 TCP 长连接特点TCP 长连接是指在通信过程中客户端和服务器之间保持一个持续的 TCP 连接而不是每次交互都重新建立和断开连接。长连接的特点包括保持连接状态在没有数据传输时通过心跳机制如定时发送检测包维持连接。减少开销避免了频繁建立和断开连接的资源消耗提高了效率。适合场景适用于需要频繁交互的场景如实时消息推送、在线监控、数据库连接等。TCP 长连接中单工和双工模式主要取决于应用程序的设计长连接单工在某些场景下长连接可能被设计为单工模式例如仅用于数据上报或日志传输。长连接双工更常见的情况是长连接支持全双工通信客户端和服务器可以随时发送和接收数据。这种模式适合实时交互场景如聊天应用或在线游戏。1.2 单工/双工通讯协议单工通讯模式单工通讯是指数据只能在一个方向上传输通信双方的角色固定发送方只能发送数据接收方只能接收数据。例如应用场景早期的计算机读卡器和打印机之间的通信。特点简单、资源消耗少但灵活性差无法实现双向交互。双工通讯模式双工通讯分为半双工和全双工两种半双工通信双方可以双向传输数据但在同一时刻只能有一个方向的数据传输。例如对讲机只能一方说话另一方接收。全双工通信双方可以同时发送和接收数据类似于电话通话。2.HTTP2.1 网络分层模型1、OSI七层模型第一层物理层网络的物理形式例如电缆、光纤、网卡、集线器等等第二层数据链路层它基本相当于 TCP/IP 的链接层第三层网络层相当于 TCP/IP 里的网际层第四层传输层相当于 TCP/IP 里的传输层第五层会话层维护网络中的连接状态即保持会话和同步第六层表示层把数据转换为合适、可理解的语法和语义第七层应用层面向具体的应用传输数据。2、TCP/IP 四层模型第一层链路层MAC 层的传输单位是帧frame第二层网络层IP 层的传输单位是包packet第三层传输层TCP 层的传输单位是段segment第四层应用层HTTP 的传输单位则是消息或报文message2.2 请求方法标准请求方法对于资源的具体操作类型由HTTP动词表示。目前 HTTP/1.1 规定了八种方法单词都必须是大写的形式GET获取资源可以理解为读取或者下载数据HEADHEAD 方法是轻量级的 GET用来获取资源的元信息POST向资源提交数据相当于写入或上传数据(理解成sql中的insert)PUT基本上是 POST 的同义词多用于更新数据(可以理解成sql中的update)DELETE删除资源CONNECT建立特殊的连接隧道OPTIONS列出可对资源实行的方法TRACE追踪请求 - 响应的传输路径。安全与幂等1.安全在 HTTP 协议里所谓的“安全”是指请求方法不会“破坏”服务器上的资源即不会对服务器上的资源造成实质的修改。按照这个定义只有GET 和 HEAD 方法是“安全”的因为它们是“只读”操作只要服务器不故意曲解请求方法的处理方式无论 GET 和 HEAD 操作多少次服务器上的数据都是“安全的”。而 POST/PUT/DELETE 操作会修改服务器上的资源增加或删除数据所以是“不安全”的。2.幂等所谓的“幂等”实际上是一个数学用语被借用到了 HTTP 协议里意思是多次执行相同的操作结果也都是相同的即多次“幂”后结果“相等”。很显然GET 和 HEAD 既是安全的也是幂等的DELETE可以多次删除同一个资源效果都是“资源不存在”所以也是幂等的。POST 和 PUT 的幂等性质就略费解一点。 按照 RFC 里的语义POST 是“新增或提交数据”多次提交数据会创建多个资源所以不是幂等的而PUT是“替换或更新数据”多次更新一个资源资源还是会第一次更新的状态所以是幂等的。2.3 报文结构1、请求/响应报文结构HTTP 协议的请求报文和响应报文的结构基本相同由三大部分组成起始行start line描述请求或响应的基本信息头部字段集合header使用 key-value 形式更详细地说明报文消息正文entity实际传输的数据它不一定是纯文本可以是图片、视频等二进制数据。2、请求行请求行由三部分构成请求方法是一个动词如 GET/POST表示对资源的操作请求目标通常是一个 URI标记了请求方法要操作的资源版本号表示报文使用的 HTTP 协议版本。3、状态行-服务器响应的状态状态行由三部分构成版本号表示报文使用的 HTTP 协议版本状态码一个三位数用代码的形式表示处理的结果比如 200 是成功500 是服务器错误原因作为数字状态码补充是更详细的解释文字帮助人理解原因。4、头部字段头部字段是 key-value 的形式key 和 value 之间用“:”分隔最后用 CRLF 换行表示字段结束。2.4 HTTP的实体数据1MIME type多用途互联网邮件扩展”Multipurpose Internet Mail Extensions简称为MIME。MIME 是一个很大的标准规范但 HTTP 只“顺手牵羊”取了其中的一部分用来标记 body 的数据类型这就是我们平常总能听到的“MIME type”。text即文本格式的可读数据我们最熟悉的应该就是 text/html 了表示超文本文档此外还有纯文本 text/plain、样式表 text/css 等。image即图像文件有 image/gif、image/jpeg、image/png 等。audio/video音频和视频数据例如 audio/mpeg、video/mp4 等。application数据格式不固定可能是文本也可能是二进制必须由上层应用程序来解释。常见的有 application/jsonapplication/javascript、application/pdf 等另外如果实在是不知道数据是什么类型像刚才说的“黑盒”就会是 application/octet-stream即不透明的二进制数据。2Encoding type但仅有 MIME type 还不够因为 HTTP 在传输时为了节约带宽有时候还会压缩数据为了不要让浏览器继续“猜”还需要有一个“Encoding type”告诉数据是用的什么编码格式这样对方才能正确解压缩还原出原始的数据。比起 MIME type 来说Encoding type 就少了很多常用的只有下面三种gzipGNU zip 压缩格式也是互联网上最流行的压缩格式deflatezlibdeflate压缩格式流行程度仅次于 gzipbr一种专门为 HTTP 优化的新压缩算法Brotli。2.5 HTTP的长连接与短连接早期的 HTTP 协议使用短连接收到响应后就立即关闭连接效率很低HTTP/1.1 默认启用长连接在一个连接上收发多个请求响应提高了传输效率服务器会发送“Connection: keep-alive”字段表示启用了长连接报文头里如果有“Connection: close”就意味着长连接即将关闭过多的长连接会占用服务器资源所以服务器会用一些策略有选择地关闭长连接“队头阻塞”问题会导致性能下降可以用“并发连接”和“域名分片”技术缓解。1HTTP/1.1 如何实现长连接HTTP/1.1 是一种无状态的超文本传输协议主要用于客户端和服务器之间的数据交互。虽然 HTTP 本身是无状态的但 HTTP/1.1 引入了长连接的概念允许客户端和服务器之间保持一个持续的 TCP 连接而不是每次请求后立即关闭连接。Connection: keep-alive在 HTTP/1.1 中长连接的核心机制是通过 Connection 头部字段实现的。默认情况下HTTP/1.1 的连接是持久的即长连接但客户端和服务器可以通过设置 Connection 头部字段来显式控制连接的行为。超时机制虽然 HTTP/1.1 支持长连接但连接不会永久保持。为了防止资源浪费服务器通常会设置一个超时时间例如 30 秒或 60 秒。如果在超时时间内没有新的请求服务器会主动关闭连接。客户端也可以通过心跳机制如发送一个空请求来保持连接活跃。2.6 HTTP的重定向和跳转重定向是服务器发起的跳转要求客户端改用新的 URI 重新发送请求通常会自动进行用户是无感知的301/302 是最常用的重定向状态码分别是“永久重定向”和“临时重定向”响应头字段 Location 指示了要跳转的 URI可以用绝对或相对的形式重定向可以把一个 URI 指向另一个 URI也可以把多个 URI 指向同一个 URI用途很多使用重定向时需要当心性能损耗还要避免出现循环跳转。2.7 HTTP的cookie机制Cookie 是服务器委托浏览器存储的一些数据让服务器有了“记忆能力”响应报文使用 Set-Cookie 字段发送“keyvalue”形式的 Cookie 值请求报文里用 Cookie 字段发送多个 Cookie 值为了保护 Cookie还要给它设置有效期、作用域等属性常用的有 Max-Age、Expires、Domain、HttpOnly 等Cookie 最基本的用途是身份识别实现有状态的会话事务。2.8 HTTP的缓存控制缓存是优化系统性能的重要手段HTTP 传输的每一个环节中都可以有缓存服务器使用“Cache-Control”设置缓存策略常用的是“max-age”表示资源的有效期浏览器收到数据就会存入缓存如果没过期就可以直接使用过期就要去服务器验证是否仍然可用验证资源是否失效需要使用“条件请求”常用的是“if-Modified-Since”和“If-None-Match”收到 304 就可以复用缓存里的资源验证资源是否被修改的条件有两个“Last-modified”和“ETag”需要服务器预先在响应报文里设置搭配条件请求使用浏览器也可以发送“Cache-Control”字段使用“max-age0”或“no_cache”刷新数据。2.9 状态码1××提示信息表示目前是协议处理的中间状态还需要后续的操作2××成功报文已经收到并被正确处理3××重定向资源位置发生变动需要客户端重新发送请求4××客户端错误请求报文有误服务器无法处理5××服务器错误服务器在处理请求时内部发生了错误。4.Webclient使用1常见Http异常SocketTimeoutException 不是 TimeoutException 的子类java.util.concurrent.TimeoutException └── reactor.core.Exceptions.ReactorTimeoutException ├── **ConnectTimeoutException** 连接超时 ├── **ReadTimeoutException** 响应/读取超时 └── WriteTimeoutException 写入超时 java.net.SocketTimeoutException (响应超时SocketTimeoutException 不是 TimeoutException 的子类2) WebClient 里最关键的异常对应表异常类含义归类ReadTimeoutException读取超时未名异常SocketTimeoutException响应超时未名异常TimeoutException整体超时未名异常ConnectTimeoutException连接建立超时连不上服务器连接异常ConnectException连接被拒绝服务不可用UnknownHostException域名解析失败DNS 异常WebClientResponseException4xx/5xx业务 / 服务异常DecodingExceptionJSON 解析失败格式异常其他异常未知错误未名异常2使用实例importlombok.extern.slf4j.Slf4j;importorg.springframework.http.HttpStatus;importorg.springframework.web.reactive.function.client.*;importreactor.core.publisher.Mono;importjava.net.ConnectException;importjava.net.SocketTimeoutException;importjava.net.UnknownHostException;importjava.nio.channels.ClosedChannelException;Slf4jpublicclassWebClientExceptionUtil{publicstaticTMonoThandleError(MonoTmono,StringapiDesc){returnmono// 1. HTTP 4xx/5xx.onErrorResume(WebClientResponseException.class,e-{HttpStatusstatuse.getStatusCode();Stringbodye.getResponseBodyAsString();log.error(【{}】HTTP状态异常 {}响应{},apiDesc,status.value(),body);returnMono.error(newBusinessException(status.is4xxClientError()?客户端请求异常:服务端异常));})// 2. 建立连接超时单独一类.onErrorResume(ConnectTimeoutException.class,e-{log.error(【{}】建立连接超时,apiDesc,e);returnMono.error(newBusinessException(连接超时));})// 3. 响应超时未名异常.onErrorResume(ex-exinstanceofReadTimeoutException||exinstanceofSocketTimeoutException,e-{log.error(【{}】响应超时,apiDesc,e);returnMono.error(newBusinessException(未名异常-响应超时));})// 4. 网络异常连接被拒、关闭、域名解析.onErrorResume(ex-exinstanceofConnectException||exinstanceofClosedChannelException||exinstanceofUnknownHostException,e-{log.error(【{}】网络异常,apiDesc,e);returnMono.error(newBusinessException(网络异常));})// 5. 解析异常.onErrorResume(DecodingException.class,e-{log.error(【{}】返回数据解析失败,apiDesc,e);returnMono.error(newBusinessException(返回格式异常));})// 6. 兜底未知异常.onErrorResume(Exceptione-{log.error(【{}】未知异常,apiDesc,e);returnMono.error(newBusinessException(未名异常));});}}2.REST概念REST即Representational State Transfer的缩写。“表现层状态转化”。如果一个架构符合REST原则就称它为RESTful架构。资源ResourcesREST的名称表现层状态转化中省略了主语。“表现层其实指的是资源”Resources的表现层。所谓资源就是网络上的一个实体或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务总之就是一个具体的实在。你可以用一个URI统一资源定位符指向它每种资源对应一个特定的URI。要获取这个资源访问它的URI就可以因此URI就成了每一个资源的地址或独一无二的识别符。所谓上网就是与互联网上一系列的资源互动调用它的URI。表现层Representation“资源是一种信息实体它可以有多种外在表现形式。我们把资源具体呈现出来的形式叫做它的表现层”Representation。比如文本可以用txt格式表现也可以用HTML格式、XML格式、JSON格式表现甚至可以采用二进制格式图片可以用JPG格式表现也可以用PNG格式表现。URI只代表资源的实体不代表它的形式。严格地说有些网址最后的.html后缀名是不必要的因为这个后缀名表示格式属于表现层范畴而URI应该只代表资源的位置。它的具体表现形式应该在HTTP请求的头信息中用Accept和Content-Type字段指定这两个字段才是对表现层的描述。状态转化State Transfer访问一个网站就代表了客户端和服务器的一个互动过程。在这个过程中势必涉及到数据和状态的变化。互联网通信协议HTTP协议是一个无状态协议。这意味着所有的状态都保存在服务器端。因此如果客户端想要操作服务器必须通过某种手段让服务器端发生状态转化State Transfer。而这种转化是建立在表现层之上的所以就是表现层状态转化。客户端用到的手段只能是HTTP协议。具体来说就是HTTP协议里面四个表示操作方式的动词GET、POST、PUT、DELETE。它们分别对应四种基本操作GET用来获取资源POST用来新建资源也可以用于更新资源PUT用来更新资源DELETE用来删除资源。5. URI与URL的区别URL——统一资源定位符Uniform Resource LocatorURI——统一资源标识符Uniform Resource IdentifierURI常用格式scheme / host:port path ? queryscheme:协议名host:port 资源所在主机名,地址端口如果不写端口浏览器使用默认的端口path:资源所在位置必须以“/”开始query: 查询参数以“?”开始但不包含“?”。keyvalue字符串用连接URI包含动词因为资源表示一种实体所以应该是名词URI不应该有动词动词应该放在HTTP协议中。URI中加入版本号http://www.example.com/app/1.0/foo http://www.example.com/app/1.1/foo http://www.example.com/app/2.0/foo因为不同的版本可以理解成同一种资源的不同表现形式所以应该采用同一个URI。版本号可以在HTTP请求头信息的Accept字段中进行区分参见Versioning REST ServicesAccept: vnd.example-com.foojson; version1.0 Accept: vnd.example-com.foojson; version1.1 Accept: vnd.example-com.foojson; version2.0