a.tcp和udp协议的区别
1)区别
对比维度 | TCP(传输控制协议) | UDP(用户数据报协议) |
连接特性 | 面向连接(通信前需三次握手建立连接,通信结束后四次挥手断开连接) | 无连接(直接发送数据,无需提前建立或维护连接) |
可靠性 | 可靠传输(保证数据按序、无丢失、无重复到达) | 不可靠传输(不保证数据到达,不处理失序或重复问题) |
传输模式 | 流式传输(数据无边界,视为连续字节流) | 数据报传输(每个数据报独立,有明确边界和长度) |
传输效率 | 较低(需连接建立、确认、重传、流量控制等机制,开销大) | 较高(无连接和复杂控制机制,延迟低、传输速度快) |
拥塞控制/流量控制 | 内置完善的拥塞控制(如慢启动、拥塞避免)和流量控制(滑动窗口) | 无内置机制,完全依赖应用层处理 |
首部开销 | 较大(固定首部 20 字节,可选字段最多 60 字节) | 较小(固定首部仅 8 字节,包含源端口、目的端口等简单字段) |
数据边界 | 无(接收方需自行处理字节流分割) | 有(每个 UDP 数据报独立,接收方直接获取完整报文) |
适用场景 | 对可靠性要求高的场景(如文件传输、网页浏览、邮件等) | 对实时性要求高的场景(如音视频流、实时游戏、DNS 查询等) |
总结:
- TCP 以“可靠性”为设计核心,适合需要数据准确无误的场景,但牺牲了部分效率;
- UDP 以“实时性”为设计核心,适合允许少量丢包但要求低延迟的场景,效率更高但需应用层自行处理可靠性问题。
b.socket概念详解
Socket(套接字) 是计算机网络中实现 进程间通信(IPC) 的基本抽象概念,是操作系统提供的网络编程接口。
它本质上是一个 端点,用于在不同主机或同一主机上的进程之间传输数据,是网络通信的基础。
1)Socket 的核心概念
本质
- 是操作系统内核提供的 网络通信抽象层,允许应用程序通过一组 API(如
send()
/recv()
)与网络交互。 - 封装了底层网络协议(如 TCP/IP、UDP)的细节,使开发者无需关心物理层和协议栈的复杂性。
定位作用
- 唯一标识网络中的一个 通信端点,由以下三要素组成:
- IP 地址:标识网络中的主机。
- 端口号:标识主机上的具体进程(如 Web 服务默认端口 80,FTP 默认端口 21)。
- 传输层协议:指定使用 TCP 或 UDP 协议。
2)Socket 的类型
根据传输层协议的不同,Socket 主要分为三种类型:
类型 | 协议 | 特点 | 典型应用 |
流式套接字 | TCP | - 面向连接,可靠传输 - 数据无边界(字节流) - 自动处理分包、排序、重传 | HTTP/HTTPS(网页浏览)、FTP(文件传输)、邮件协议 |
数据报套接字 | UDP | - 无连接,不可靠传输 - 数据有边界(每个数据报独立) - 低延迟、高效率 | 实时音视频(如视频会议、直播)、DNS 查询、在线游戏 |
原始套接字 | 原始协议 | - 直接访问网络层(如 IP)或数据链路层(如 MAC) - 需系统权限(如 root) | 网络抓包工具(如 Wireshark)、自定义协议开发 |
3)Socket 的组成要素
IP 地址
- 标识网络中的目标主机,如
192.168.1.1
(IPv4)或2001:db8::1
(IPv6)。
端口号
- 16 位无符号整数(范围:0~65535),用于区分同一主机上的不同进程。
- 知名端口(0~1023):系统保留,如 80(HTTP)、443(HTTPS)、22(SSH)。
- 动态端口(1024~65535):由操作系统动态分配给应用程序。
传输层协议
- 决定通信的可靠性和效率:
- TCP:适用于需要可靠传输的场景(如文件传输)。
- UDP:适用于实时性要求高的场景(如视频流)。
4)Socket 的工作流程
服务器端流程
创建 Socket(socket()) → 绑定地址(bind()) → 监听连接(listen()) → 接受连接(accept()) → 收发数据(send()/recv()) → 关闭 Socket(close())
- socket():创建 Socket 对象,指定协议类型(如 TCP)。
- bind():将 Socket 绑定到本地 IP 地址和端口号(如服务器端口 8080)。
- listen():设置为监听状态,等待客户端连接。
- accept():阻塞式等待,接受客户端连接,返回新的 Socket(用于与该客户端通信)。
- send()/recv():通过新 Socket 与客户端收发数据。
- close():关闭 Socket,释放资源。
客户端流程
创建 Socket(socket()) → 连接服务器(connect()) → 收发数据(send()/recv()) → 关闭 Socket(close())
- connect():指定服务器的 IP 地址和端口号,发起连接(触发 TCP 三次握手)。
- 其余步骤与服务器端类似。
5)Socket 的应用场景
典型场景
- TCP Socket:
- Web 服务(HTTP/HTTPS):浏览器通过 TCP Socket 与服务器通信。
- 即时通讯(如微信):消息传输需要可靠性。
- UDP Socket:
- 实时游戏(如《王者荣耀》):低延迟比数据可靠性更重要。
- 视频会议(如 Zoom):允许少量丢包,但要求画面流畅。
6)Socket 与端口的关系
- 端口 是传输层协议(TCP/UDP)的概念,用于标识进程;
- Socket 是应用层通过操作系统访问网络的接口,包含 IP+端口+协议 三要素。
- 同一主机上的多个 Socket 可以通过不同端口区分(如 Web 服务器监听 80 端口,FTP 服务器监听 21 端口)。
c.使用python实现tcp与udp通信
1)TCP 通信示例
1. TCP 服务器端 (tcp_server.py
)
import socket
def tcp_server():
# 创建 TCP Socket 对象(AF_INET 表示 IPv4,SOCK_STREAM 表示 TCP)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定 IP 地址和端口
server_address = ('localhost', 8888)
server_socket.bind(server_address)
# 监听连接(最大连接数 5)
server_socket.listen(5)
print(f"TCP 服务器已启动,监听地址: {server_address}")
while True:
# 接受客户端连接(阻塞直到有连接)
client_socket, client_address = server_socket.accept()
print(f"接受来自 {client_address} 的连接")
# 接收客户端数据(最多 1024 字节)
data = client_socket.recv(1024)
if data:
message = data.decode('utf-8')
print(f"收到消息: {message}")
# 回显消息给客户端
response = f"服务器已收到: {message}"
client_socket.sendall(response.encode('utf-8'))
# 关闭客户端连接
client_socket.close()
if __name__ == "__main__":
tcp_server()
2. TCP 客户端 (tcp_client.py
)
import socket
def tcp_client():
# 创建 TCP Socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
server_address = ('localhost', 8888)
client_socket.connect(server_address)
try:
# 发送消息到服务器
message = "Hello, TCP Server!"
client_socket.sendall(message.encode('utf-8'))
# 接收服务器响应
data = client_socket.recv(1024)
print(f"收到服务器响应: {data.decode('utf-8')}")
finally:
# 关闭连接
client_socket.close()
if __name__ == "__main__":
tcp_client()
2)UDP 通信示例
1. UDP 服务器端 (udp_server.py
)
import socket
def udp_server():
# 创建 UDP Socket 对象(SOCK_DGRAM 表示 UDP)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 IP 地址和端口
server_address = ('localhost', 9999)
server_socket.bind(server_address)
print(f"UDP 服务器已启动,监听地址: {server_address}")
while True:
# 接收客户端数据(自动获取客户端地址)
data, client_address = server_socket.recvfrom(1024)
if data:
message = data.decode('utf-8')
print(f"收到来自 {client_address} 的消息: {message}")
# 回显消息给客户端
response = f"服务器已收到: {message}"
server_socket.sendto(response.encode('utf-8'), client_address)
if __name__ == "__main__":
udp_server()
2. UDP 客户端 (udp_client.py
)
import socket
def udp_client():
# 创建 UDP Socket 对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 服务器地址和端口
server_address = ('localhost', 9999)
try:
# 发送消息到服务器(无需先连接)
message = "Hello, UDP Server!"
client_socket.sendto(message.encode('utf-8'), server_address)
# 接收服务器响应
data, server = client_socket.recvfrom(1024)
print(f"收到服务器 {server} 的响应: {data.decode('utf-8')}")
finally:
# 关闭 Socket
client_socket.close()
if __name__ == "__main__":
udp_client()
3)运行
TCP 通信测试
- 启动服务器:
python3 tcp_server.py
- 启动客户端(新终端):
python3 tcp_client.py
- 观察输出:
- 服务器显示:
接受来自 ('127.0.0.1', xxxx) 的连接
和收到的消息。 - 客户端显示:
收到服务器响应: 服务器已收到: Hello, TCP Server!
UDP 通信测试
- 启动服务器:
python3 udp_server.py
- 启动客户端(新终端):
python3 udp_client.py
- 观察输出:
- 服务器显示:
收到来自 ('127.0.0.1', xxxx) 的消息: Hello, UDP Server!
- 客户端显示:
收到服务器 ('127.0.0.1', 9999) 的响应: 服务器已收到: Hello, UDP Server!
4)区别对比
特性 | TCP 实现 | UDP 实现 |
连接建立 | 需要 | 无需连接,直接发送 |
数据收发 | 使用 | 使用 |
可靠性 | 可靠(自动处理丢包、重传) | 不可靠(可能丢包) |
关闭方式 | 需要显式关闭客户端连接 | 直接关闭 Socket |
适用场景 | 文件传输、网页浏览 | 实时音视频、游戏 |
5)tcp聊天应用
TCP 聊天服务器 (tcp_chat_server.py
)
import socket
def tcp chat server():
# 创建TCP 服务器 Socket
server socket=socket.socket(socket.AF INET, socket.SOCK STREAM)
server_socket.bind(('127.0.0.1',12345))# 绑定 IP 和端口
server socket.listen(5)#开始监听
print('Server is waiting for connection...'
client_socket,client_address=server_socket.accept()# 接受客户端连接
print(f'Connection established with {client address}')
while True:
#接收客户端消息
message =client_socket.recv(1024)#接收消息if not message:
break #如果没有接收到消息,则退出
print('Client:',message.decode('utf-8'))#打印客户端消息response=input('You:')#从服务器端输入回应
client socket.send(response.encode('utf-8'))#发送回应给客户端
8 def receive_messages
#*“接收井显示服务器
while True
try
me55age
print(mes
except
client_socket.close()#关闭客户端连接
server_socket.close()#关闭服务器连接
if_name_=='main'
tcp_chat server()
TCP 聊天客户端 (tcp_chat_client.py
)
import socket
def tcp chat client():
# 创建TCP 客户端 Socket
client socket =socket.socket(socket.AF INET, Socket.SOCK STREAM)
client_socket.connect(('127.0.0.1',12345))#连接服务器
while True:
message=input('You:')#从用户输入获取消息if message.lower()=='exit':#输入exit 退出聊天
break
client socket.send(message.encode('utf-8'))#发送消息
response=client_socket.recv(1024)#接收服务器响应
print('Server:',response.decode('utf-8'))# 打印服务器响应
client socket.close()
if_name_=='_main_':
tcp_chat_client()
运行
启动服务器:
python3 tcp_chat_server.py
启动客户端(可多开):
python3 tcp_chat_client.py
聊天操作:
- 输入昵称后即可开始聊天。
- 输入
quit
退出聊天。