1、TCP协议
位于传输层, 提供可靠的字节流服务,传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。字节流服务(Byte Stream Service) 是指, 为了方便传输, 将大块数据分割成以报文段(segment) 为单位的数据包进行管理。TCP连接相当于两根管道(一个用于服务器到客户端,一个用于客户端到服务器),管道里面数据传输是通过字节码传输,传输是有序的,每个字节都是一个一个来传输。
特点
TCP是面向连接的
每条TCP连接只能用于两个断点,一对一
TCP提供可靠交付的服务:连接传输数据、无差错、不丢失、不重复、并且按序到达
TCP提供全双工通信
面向字节流,TCP根据对方给出的窗口和当前网络拥塞的程度来决定一个报文应该包含多少个字节
三次握手

一个虚拟连接的建立是通过三次握手来实现的
(发送方) –> [SYN] –> (接收方)
注意: 一个 SYN包就是仅SYN标记设为1的TCP包(发送方) <– [SYN/ACK] <–(接收方)
注意: SYN/ACK包是仅SYN 和 ACK 标记为1的包(表示对第一个SYN包的确认)(发送方) –> [ACK] –> (接收方)
注意: ACK包就是仅ACK 标记设为1的TCP包

SYN、ACK是标志位:确认方ACK=发起方Seq+1,两端配对。
seq、ack是数据包序号
疑问:为什么三次握手最后一次握手中, 在上面的示意图中回复的 seq = x+1 ?
因为TCP 规定SYN=1的报文段不能携带数据, 但要消耗掉1个序列号。
为什么要三次握手
三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
所以三次握手就能确认双发收发功能都正常,缺一不可。
第2次握手传回了ACK,为什么还要传回SYN?
接收端传回发送端所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号了,这表明从客户端到服务端的通信是正常的。而回传SYN则是为了建立并确认从服务端到客户端的通信。
YSN:同步序列编号(Synchronize Sequence Numbers)
ACK: 确认字符(Acknowledge character)
FIN:结束标志
seq和ack号存在于TCP报文段的首部中,seq是序号,ack是确认号,大小均为4字节
TCP四次挥手
TCP连接是全双工的,因此每个方向都需要建立连接,且每个方向都必须单独进行关闭。

TCP规定,FIN=1的报文段不能携带数据, 但要消耗掉1个序列号
第一次挥手(不能发数据,可以接收数据):当客户端的数据都传输完成后,客户端向服务端发出连接释放报文(当然数据没发完时也可以发送连接释放报文并停止发送数据),释放连接报文包含FIN标志位(FIN=1)、序列号seq=1101(100+1+1000,其中的1是建立连接时占的一个序列号)。需要注意的是客户端发出FIN报文段后只是不能发数据了,但是还可以正常收数据;另外FIN报文段即使不携带数据也要占据一个序列号。
第二次挥手(关闭等待状态,还没有关闭,还可以进行发送数据):服务端收到客户端发的FIN报文后给客户端回复确认报文,确认报文包含ACK标志位(ACK=1)、确认号ack=1102(客户端FIN报文序列号1101+1)、序列号seq=2300(300+2000)。此时服务端处于关闭等待状态,而不是立马给客户端发FIN报文,这个状态还要持续一段时间,因为服务端可能还有数据没发完。
第三次挥手(最后的数据发送完毕发送):服务端将最后数据(比如50个字节)发送完毕后就向客户端发出连接释放报文,报文包含FIN和**ACK标志位(FIN=1,ACK=1)、确认号和第二次挥手一样ack=1102、序列号seq**=2350(2300+50)。
第四次挥手(服务端释放TCP连接,客户端等待2MSL后释放):客户端收到服务端发的FIN报文后,向服务端发出确认报文,确认报文包含**ACK标志位(ACK=1)、确认号ack=2351、序列号seq**=1102。
注意:客户端发出确认报文后不是立马释放TCP连接,而是要经过2MSL(最长报文段寿命的2倍时长)后才释放TCP连接。而服务端一旦收到客户端发出的确认报文就会立马释放TCP连接,所以服务端结束TCP连接的时间要比客户端早一些。
为什么建立连接协议是三次握手,而关闭连接却是四次握手?
因为只有在客户端和服务端都没有数据要发送的时候才能断开TCP。而客户端发出FIN报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的FIN报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的FIN报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发FIN报文(所以不能一次性将确认报文和FIN报文发给客户端,就是这里多出来了一次)。
为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?(字节面试问到过)
如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
字节流方式
2、UDP协议
UDP首部格式
UDP协议分为首部字段和数据字段,其中首部字段只占用8个字节,分别是个占用两个字节的源端口、目的端口、长度和检验和。
首部字段

- 源端口 源端口号。在需要对方回信时。不需要时可用全0
- 目的端口 目的端口号。这在终点交付报文时必须使用
- 长度 UDP 用户数据报的长度,其最小值是8(仅有首部)
- 检验和 检测 UDP 用户数据报在传输中是否有错。有错就丢弃
UDP是**传输层**的协议,无连接协议,也称透明协议
UDP 是无连接的,即发送数据之前不需要建立连接(发送数据结束时也没有连接可释放),减少了开销和发送数据之前的时延
UDP 使用尽最大努力交付,即不保证可靠交付,主机不需要维持复杂的连接状态表
UDP 是面向报文的,发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界
UDP 支持一对一、一对多、多对一和多对多的交互通信
UDP 没有拥塞控制,网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的
UDP 的首部开销小,只有8个字节,比 TCP 的20个字节的首部要短
报文方式
位于传输层的TCP数据分组称为段(Segment),又译为报文段、数据段或分段。TCP将来自应用层的数据分块并封装成TCP段进行发送。TCP段封装在IP数据报中,然后再封装成数据链路层中的帧
3、Websocket
全双工通讯的协议
借助于Http协议进行连接,当客户端连接到服务端的时候会向服务端发送一个类似下面的HTTP报文:

这是一个HTTP的get请求报文,注意该报文中有一个upgrade首部,它的作用是告诉服务端需要将通信协议切换到websocket。如果服务端支持websocket协议,那么它就会将自己的通信协议切换到websocket,同时发给客户端类似于以下的一个响应报文头:

返回的状态码为101,表示同意客户端协议转换请求,并将它转换为websocket协议。以上过程都是利用HTTP通信完成的,称之为websocket协议握手。
4、TCP、UDP、WebSocket区别
| TCP | UDP | Websocket |
|---|---|---|
| 面向连接的传输,通信前要先建立连接(三次握手机制) | 无连接的传输,通信前不需要建立连接 | 连接 |
| 靠的传输(有序,无差错,不丢失,不重复) | 不可靠的传输 | 可靠协议 |
| 面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组 | 面向数据报的传输,没有分组开销 | |
| 拥塞控制和流量控制机制 | 不提供拥塞控制和流量控制机制 |
5、HTTP
1、http协议介绍
http(Hypertext transfer protocol)超文本传输协议,它是互联网上应用最为广泛的一种网络协议,工作在应用层。基于TCP协议(传输层)之上,规定WWW服务器 , 是浏览器之间信息传递规范。使用的默认端口号为80端口。https默认端口是443。
2、http与https区别
| http | https | |
|---|---|---|
| 是否加密 | 未加密,明文 | SSL(ca证书)+http加密 |
| 端口 | 80 | 443 |
| 传输加密 | 明文传输 | 加密传输 |
3、http版本区别
与tcp区别
在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
| http0.9(1991) | Http1.0(1996) | http1.1(1999) | http2.0(2015) | |
|---|---|---|---|---|
| 请求类型 | GET | POST、GET、HEAD | PUT、DELETE、CONNECT、TRACE、OPTIONS | 多路复用 |
| 连接类型 | GET请求 | 短连接(一次请求建议一次TCP连接,请求完就断开)耗时 | 长连接(一次TCP连接可以多次请求)心跳保持 | 服务器主动推送,解析基于二进制,降低开销(一次TCP连接可以处理多个请求) |
| 头部 | 不支持请求头 | 支持cache, MIME, method | 支持 | 支持 |
| 传输文件 | 纯文本,不能传输图片 | 任何格式文件 | 任何格式文件 | 任何格式 |
| 使用情况 | 已经淘汰 | 比较常用 | 常用 | 不常用,下一代http协议 |
4、http无状态
TCP的面向连接是传输层的,而HTTP的无状态则是应用层的

5、查看接口使用的http版本
打开开发者选项,刷新页面后点击一个请求,右键->Header Options->Protocol(打开)

出现Protocol后即可看到请求的版本类型

6、HTTP与RPC区别
| 不同点 | http | RPC |
|---|---|---|
| 通信协议 | 文本协议 | 二进制协议 |
| 调用方式 | 通过 URL 进行调用 | 通过函数调用进行调用 |
| 参数传递方式 | 使用 URL 参数或者请求体进行参数传递 | 使用函数参数进行传递 |
| 接口描述方式 | 接口使用 RESTful 架构描述接口 | 使用接口定义语言(IDL)描述接口 |
| 性能表现 | RPC 接口通常比 HTTP 接口更快,因为它使用二进制协议进行通信,而且使用了一些性能优化技术,例如连接池、批处理等。此外,RPC 接口通常支持异步调用,可以更好地处理高并发场景 |
6、长连接、短连接、长轮询、短轮询区别
| 短连接 | 长连接 |
|---|---|
| 每次Http请求都会建立Tcp连接,管理容易 | 只需要建立一次Tcp连接,以后Http请求重复使用同一个Tcp连接,管理难 |
应用场景
一般长连接(追求实时性高的场景)用于少数client-end to server-end的频繁的通信,例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接(追求资源易回收场景),因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源。
| 短轮询 | 长轮询 |
|---|---|
| 重复发送Http请求,查询目标事件是否完成 | 在服务端hold住Http请求(死循环或者sleep等等方式),等到目标时间发生(保持这个请求等待数据到来或者恰当的超时),返回Http响应 |
| 优点:编写简单,缺点:浪费带宽和服务器资源 | 优点:在无消息的情况下不会频繁的请求,缺点:编写复杂 |
短轮询和长轮询和短连接和长连接有本质区别
- 长、短连接是客户端与服务端建立和保持TCP连接的机制。
- 长、短轮询是指客户端请求服务端,服务端给予应答的方式。