一、TCP(传输控制协议)
1. 原理
TCP 处于传输层,负责为应用层提供可靠的、面向连接的字节流服务。在数据传输前,它会通过"三次握手"建立连接,确保通信双方都具备收发数据的能力;传输过程中,采用确认机制、重传机制和滑动窗口机制保证数据的可靠和有序;传输结束后,使用"四次挥手"断开连接。
三次握手建立连接
- 第一次握手:客户端向服务器发送一个 SYN 包,其中
seq = x
(x
为客户端随机生成的初始序列号),表明客户端希望与服务器建立连接。 - 第二次握手:服务器收到 SYN 包后,向客户端发送 SYN + ACK 包。SYN 表示同意建立连接,
seq = y
(y
为服务器随机生成的初始序列号);ACK 是对客户端 SYN 包的确认,ack = x + 1
。 - 第三次握手:客户端收到 SYN + ACK 包后,向服务器发送 ACK 包,
seq = x + 1
,ack = y + 1
,此时连接建立成功。
四次挥手断开连接
- 第一次挥手:客户端向服务器发送 FIN 包,
seq = u
,表示客户端没有数据要发送了,请求关闭连接。 - 第二次挥手:服务器收到 FIN 包后,向客户端发送 ACK 包,
seq = v
,ack = u + 1
,表示同意关闭客户端到服务器的连接。 - 第三次挥手:服务器向客户端发送 FIN 包,
seq = v
,表示服务器也没有数据要发送了,请求关闭服务器到客户端的连接。 - 第四次挥手:客户端收到 FIN 包后,向服务器发送 ACK 包,
seq = u + 1
,ack = v + 1
,连接关闭。
2. 时序图
3. 代码示例(Python)
import socket# 创建 TCP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
server_socket.bind(('localhost', 8888))
# 监听连接
server_socket.listen(1)print('Waiting for a connection...')
# 接受客户端连接
conn, addr = server_socket.accept()
print(f'Connected by {addr}')while True:# 接收客户端数据data = conn.recv(1024)if not data:break# 发送响应数据conn.sendall(data)# 关闭连接
conn.close()
二、UDP(用户数据报协议)
1. 原理
UDP 是一种无连接的传输层协议,不保证数据的可靠传输和顺序性。发送方直接将数据封装成 UDP 数据报发送,接收方接收数据报,无需事先建立连接和后续断开连接的操作。每个 UDP 数据报包含源端口、目的端口、长度和校验和等信息。
2. 时序图
3. 代码示例(Python)
import socket# 创建 UDP 套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定地址和端口
server_socket.bind(('localhost', 8888))print('Waiting for data...')
while True:# 接收数据data, addr = server_socket.recvfrom(1024)print(f'Received from {addr}: {data.decode()}')# 发送响应数据server_socket.sendto(data, addr)
三、WebSocket
1. 原理
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,工作在应用层。它基于 TCP 协议,通过 HTTP 协议进行握手升级。客户端发送 HTTP 请求,请求头包含 Upgrade: websocket
字段,服务器若支持则返回状态码为 101 的 HTTP 响应,表示同意升级。之后双方可通过 WebSocket 进行实时双向通信。
2. 时序图
3. 代码示例(Python + Flask-SocketIO)
from flask import Flask
from flask_socketio import SocketIOapp = Flask(__name__)
socketio = SocketIO(app)@socketio.on('connect')
def handle_connect():print('Client connected')@socketio.on('message')
def handle_message(message):print(f'Received message: {message}')socketio.send('Server received: ' + message)if __name__ == '__main__':socketio.run(app, debug=True)
四、HTTP(超文本传输协议)
1. 原理
HTTP 是应用层协议,基于 TCP 协议实现。它是无状态的,即服务器不会记录客户端的历史请求信息。采用请求 - 响应模式,客户端向服务器发送请求,服务器根据请求进行处理并返回响应。
请求结构
- 请求行:包含请求方法(如 GET、POST 等)、请求 URI 和 HTTP 版本。
- 请求头:包含一系列键值对,如
User - Agent
表示客户端信息,Content - Type
表示请求体的类型等。 - 请求体:可选部分,用于携带请求的数据,如表单数据、JSON 数据等。
响应结构
- 状态行:包含 HTTP 版本、状态码和状态消息,如
200 OK
表示请求成功。 - 响应头:同样包含一系列键值对,如
Content - Length
表示响应体的长度,Content - Type
表示响应体的类型。 - 响应体:包含服务器返回的实际数据,如 HTML 页面、JSON 数据等。
2. HTTP 与 TCP 的区别
- 层次不同:TCP 是传输层协议,负责数据的可靠传输;HTTP 是应用层协议,基于 TCP 提供的服务进行应用数据的传输。
- 连接特性:TCP 是面向连接的,在传输数据前需要建立连接,传输后断开连接;HTTP 本身是无状态的,每次请求都是独立的,虽然基于 TCP 连接,但连接可以复用也可以每次重新建立。
- 功能侧重点:TCP 主要关注数据传输的可靠性、顺序性和流量控制;HTTP 关注的是如何在客户端和服务器之间传输超文本等应用数据,以及如何处理请求和响应。
3. 时序图
4. 代码示例(Python + Flask)
from flask import Flaskapp = Flask(__name__)@app.route('/')
def hello_world():return 'Hello, World!'if __name__ == '__main__':app.run(debug=True)
五、对比表格
协议 | 优点 | 缺点 | 实际使用场景 |
---|---|---|---|
TCP | 可靠传输,适合对数据准确性要求高的场景;面向连接,能保证数据按序到达 | 建立和断开连接开销大;传输效率相对较低 | 文件传输、电子邮件、网页浏览等 |
UDP | 无连接,开销小,传输速度快;适合实时性要求高的场景 | 不可靠传输,可能会丢包、乱序 | 实时音视频传输、在线游戏等 |
WebSocket | 全双工通信,实时性强;可以在浏览器和服务器之间进行实时通信 | 服务器资源消耗大;协议复杂度较高 | 实时聊天、实时数据更新、在线协作等 |
HTTP | 简单易用,无状态,适合快速处理请求;广泛应用于 Web 开发 | 每次请求都需要建立新的连接,开销大;不适合实时通信 | 网页浏览、API 调用等 |
六、实际使用场景总结
TCP
- 文件传输:如 FTP(文件传输协议),确保文件完整无误地传输。
- 电子邮件:SMTP(简单邮件传输协议)、POP3(邮局协议版本 3)和 IMAP(互联网邮件访问协议)等协议都基于 TCP,保证邮件的可靠传输。
- 网页浏览:HTTP 协议通常基于 TCP 传输,确保网页内容准确无误地显示给用户。
UDP
- 实时音视频传输:如 VoIP(网络电话)、视频会议等,对实时性要求高,允许一定的丢包。
- 在线游戏:游戏中的实时位置更新、动作同步等需要低延迟,UDP 更适合。
WebSocket
- 实时聊天:如即时通讯软件,用户可以实时收发消息。
- 实时数据更新:如股票行情、天气预报等,服务器可以实时推送最新数据。
- 在线协作:如多人在线文档编辑、多人游戏等,实现实时协作。
HTTP
- 网页浏览:用户通过浏览器访问网页,浏览器向服务器发送 HTTP 请求,服务器返回网页内容。
- API 调用:前后端分离的开发模式中,前端通过 HTTP 请求调用后端的 API 接口获取数据。