HTTP UDP TCP基础知识

235 阅读10分钟

HTTP发展

网络协议分层

  • 物理层(physical layer):定义物理设备如何传输数据
  • 数据链路层(datalink layer):在通信的实体之间建立数据链路连接
  • 网络层(network layer): 数据在节点之间创建逻辑链路 IP协议就在这层
  • 传输层(transport layer): TCPIP UDP 提供端到端的服务,数据分片,组装。 向高层屏蔽了下层数据通信的细节
  • 应用层:为应用软件提供了服务,构建与TCP协议之上,屏蔽网络传输相关细节 (HTTP DNS)

历史

  • ver 0.9 : 只有GET一个命令,没有HEADER,发送完就关闭TCP连接。一个TCP连接里面可以有多个HTTP请求
  • ver 1.0 : 增加了很多命令,增加了header和status code ,多字符集支持,多部分发送,权限,缓存
  • ver 1.1 :优化,增加了持久连接,建立TCP成本较高;pipeline 发送请求,增加host和其他命令。
  • ver 2: 还未普及,所有数据通过二进制传输,同一个连接里发送数据不需要按照顺序,header信息压缩以及推送效率提高。可以并发

概念

HTTP不存在连接的概念,只有request和response,在user和server中间维持通信或者说提供通信链路的是TCP协议。 TCP三次握手,就是三次传输验证。

URI URL

URI : Uniform Resource Identifier 。为了定位某个资源,用来唯一标识互联网上的信息资源,包括URL URN email地址也是URI,但是不是location

URL: uniform resource locator 统一资源定位器 协议://(user@) hostname.com: port 默认80 一般不带/path? 这是路由 schema://(user:pass@)hostname

  • fpt http https
  • user 很少用 不安全
  • hostname 直接是IP地址或者是domain domain需要DNS解析
  • port 默认80 公开的资源一般不带,难以记忆
  • /path router路由,
  • 搜索参数,
  • hash 代表返回的文件的某一个片段,使用hash作为锚点 anchor

URN: 永久统一资源定位符 很少用

报文message

分为请求报文和响应报文,request message 和 response message。

请求报文由method URI httpversion body blankline 和 header组成。

相应报文第一行里面是httpversion status和reason phrase 然后是header(date content-type))和body

对于request和response不同 header里面是关键字键值对。通知服务器有关客户端请求的信息。

  • User-Agent
  • Accept
  • Host

HTTP方法

用来定义对资源的操作

  • GET: get resource
  • POST: 传输实体主体,主要目的不是获取相应的主题内容
  • OPTION:询问支持的方法
  • UPDATE
  • DELETE:PUT相反,删除文件但是不带验证
  • PUT: 上传文件 但是1.1不带验证,需要额外操作
  • HEAD 和GET类似但是不返回报文主体,用于验证资源有效性

HTTP CODE

  • 1XX: Informational 接受的请求正在处理
  • 2XX: Success 请求正常处理完毕
  • 3XX Direction 需要进行附加操作以完成请求
  • 4XX:Client Error 服务器无法处理
  • 5XX:Server Error 服务器请求出错

2XX

200 OK

204 No Content

成功处理但是返回不含body,客户端发信息但是不返回新信息(cookie 不更新的时候)

206 Parital Content

客户端进行了范围请求

3XX

请求成功但是需要额外的一些操作以返回结果

301 Moved Permanently

改资源已经被分配了新的URI,永久重定向

302 Found

临时重定向,将来可能还发生变化

303 See Other

表示应该使用GET method。 可能发生在使用post 访问了一个程序

304 Not Modified

请求报文中有额外条件,但是未满足。 或者是在分级缓存机制中

4XX

400 Bad Request

请求报文有语法错误

401 Unauthorized

需要认值,会弹出窗口

403 Forbidden

请求报文被服务端拒绝,可能不会给出原因

404 Not Found

服务器没有找到请求的资源,或者请求被拒绝

5XX

500 Internal Server Error

服务器端在处理请求时发生了错误

503 Service Unavailable

服务器不可用

使用Node创建一个简单的HTTP服务

const http = require('http')

http.createServer(function (request, response){
    console.log('request come', request.url)
    response.end('123')
    
}).listen(8880)

Stateless

本身stateless带来了很多好处比如能快速处理大量事务,保持协议的可伸缩性。但是当web越来越复杂,比如购物网站,stateless已经不能满足需求,cookies(在http1.1)应运而生。

Persistent Connections

持久连接,也称为HTTP keep-alive,http1.1 所有连接默认持久连接。 管线化和并发


UDP协议

UDP是一种无连接的网络协议,主要用于小文件的传输或者实时数据发送比如视频会议。

  • 最大努力交付,不可靠,在丢包的时候并不会有应对措施所以不适合大文件传输
  • 面向报文,应用层有多大的报文,UDP加上8bytes的header然后发送,但是报文有1500bytes的长度限制,强制分片会带来不可靠。
  • 没有拥塞控制,适合很多实时应用,允许丢包。

Header

8bytes = 64bits = 源端口号+目的端口号(16+16) 16bits UDP长度,首部和数据的长度,数据不一定 首部8b 这16bits最多65535但是 一个报文最长1500B

16位UDP校验和,验证首部/数据有错误, 如果有错就丢弃。若目的主机相关端口被占用,会返回一个ICMP,

TCP协议

TCP协议位于传输层,面向连接,可靠的,基于字节流的传输层通信协议。

  • 面向连接,三次握手,四次挥手说的就是连接过程
  • 每一个TCP只有2个端点,点对点,也就是说TCP是不同计算机之间的进程的通信
  • TCP提供可靠的服务,有序可靠,不丢不重
  • TCP提供全双工通信,双方可以同时收发数据(半双工就是双方只有一方能发或者收)。在收发两端都有发送缓存和接收缓存,发送缓存是一个准备发送的队列,接收缓存是一个准备接收的队列。

TCP报文首部字段

TCP面向字节流,固定的20字节的TCP首部,32bytes是4字节。这样的4字节有五组,接下来介绍这5组。

第一组32bytes

前16源端口 后16目标端口

第二组32bytes

32bits 序号,tcp报文是连续的,因此需要记录本报文字节流的第一个字节在整个数据流中的序号

第三组

32bits 确认号 是期望收到对方下一个报文段的第一个字节的序号,若为N,则前N-1字节都已经收到

第四组

16bits: 数据偏移4bits+保留6bits+6bits单bits位 数据偏移: ACK: 1表示确认号valid, 0表示数据段不包含确认信息,确认号忽略 PSH: RST: 1--reset SYN 1--发起连接 同步 FIN 1--结束连接 URG: 1--紧急指针

16bits: 窗口

第五组

紧急指针和检验和

3次握手过程,建立连接

第一次挥手

Client SYN=1(发起连接) seq=x(random) 第一次是连接请求报文段,无应用层数据

第二次挥手

Serer assign ports buffer var return SYN=1 ACK=1(确认号valid) seq=y(random) ack=x+1 分配端口 缓存 变量 返回序号y 是一个32位随机值 确认号x+1 表示收到了发送过来的序号,+1表示下次发送过来的序号应该是x+1

第三次挥手

Client assign 缓存和变量,并向服务端确认返回的确认,可以携带数据 SYN=0(不用新发起连接,要发数据了)ACK=1(确认号valid,收到了服务器的确认请求),seq=x+1, ack=y+1

四次挥手 释放连接

第一次挥手

Client 发送连接释放报文,FIN=1, seq=u(之前发送的最后一个字节序号+1)

没有ACK和ack是因为已经不发送信息了,server不需要知道更多

第二次挥手

Server return ACK=1, seq=v, ack=u+1 此时Client已经不能发送数据,但是Server可以最后发送一次,seq继续

第三次挥手

Server 不能发送数据,只能send header Fin=1 ACK=1 ack=u+1 seq = w(w 不一定等于v,第二次挥手可能发送数据,否则w=v)

第四次挥手

Client 收到Fin=1 之后 返回确认报文 ACK=1, seq=u+1, ack=w+1 发送完毕等待两个时钟周期后关闭。

若第四次挥手server没有收到 会超时重传,这就是为什么要等待

TCP可靠传输

  • 伪首部,验证TCP报文是否收错了,http协议号是否是对的
  • 序号,用于验证数据队列
  • 确实 验证数据接受
  • 重传 TCP的发送方在规定时间内没有收到确认就要重传已经发送的报文段,重传时间是动态改变的,依据RTTS

TCP流量控制

当发送方速度快 接收方速度慢,就会产生大量的丢包。TCP通过滑动窗口机制来实现流量控制。 滑动窗口的大小表示接收方还有多大的缓冲区间用于接收数据,发送方可以通过滑动窗口大小确定应该发送多少 滑动窗口为0,发送方不再发送数据,但是有两种情况除外,

  • 发送紧急数据,允许用户终止在远端机上的运行进程,
  • 发送发可以发送一个1字节的数据报来通知接收方重新声明

拥塞控制

当拥塞出现时,发送方会不断重传,导致更加拥塞,应该降低发送速率。流量控制是降低发送数据大小,拥塞控制是控制发送频率

  • 慢开始,拥塞避免,快重传,快恢复
  • 维护CWND表示一个单位数据的大小
  • 慢开始--一开始只发一个单位的数据,当收到确认,每次发送单位翻倍
  • 当单位大小超过阈值,进入拥塞避免,每次单位只加1
  • 若超时,阈值/2,重新慢开始

丢包的时候进入快重传,立刻重传丢失的包,并且之间进入拥塞避免 阈值 = cwnd/2 cwnd=阈值

慢开始和快恢复指的其实是阈值

TCP常见面试题

为什么连接3次握手 关闭4次挥手?

为什么不能用两次握手进行连接?

两次握手对于Client没有任何变化,Client的req收到了res并且确认序号,但是Server并没有确认Client的序号,并不能表示Server真正收到了Client的req。不能保证连接有效性

另一方面,若网络拥塞,可能会造成连接报文重复发送,导致已经关闭的连接再次被打开

如果建立了连接但是客户端突然故障怎么办

TCP在服务端有一个保活计时器,每次客户端成功请求会重置该计时器,若2h内没有收到回复,则每隔75s重新发送一次,连续10次没有回应则认为客户端故障,关闭通信

SYN泛洪攻击

  • 泛洪攻击利用了建立连接的3次攻击,频繁发送SYN置1的请求报文,造成大量的网络端口挂起但是无法建立连接。服务端还会频繁发送确认报文,更加浪费资源

序号seq为什么要随机?

为了增加安全性,避免被第三方猜测到,从而被第三方伪造的RST报文 reset。

三次握手的第一次可以携带数据吗?

不可以,第一是会增大泛红攻击的危险性,浪费内存

三次握手第三次可以携带数据吗

可以,此时对于客户端来说已经建立连接,知道服务器接收发送功能正常。