下面我将详细讲解如何使用Python的socket库高效传输视频数据帧(连续发送图片)。
首先,为了方便测试,我准备了两张测试图片,分别命名为test1.png
和test2.png
。
- 客户端代码示例
下面是客户端代码的示例,主要是用来不断发送图片数据给服务器:
import socket
import struct
# 定义图片文件名和服务器地址
file_name = 'test1.png'
server_addr = ('localhost', 8000)
# 创建TCP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_addr)
# 发送图片到服务器
with open(file_name, 'rb') as f:
# 读取图片数据
img_data = f.read()
# 获取图片数据长度
img_len = len(img_data)
# 打包头部信息
head_fmt = '>I%ds' % len(file_name)
head_data = struct.pack(head_fmt, img_len, file_name.encode())
# 发送头部信息
sock.send(head_data)
# 发送图片数据
sock.send(img_data)
# 关闭套接字
sock.close()
该示例代码首先把需要传输的图片数据读入内存,然后打包它的头部信息并发送给服务器,最后再把图片数据发送给服务器。头部信息的格式为:图片长度 + 图片文件名长度 + 图片文件名
,使用了Python中的struct
模块打包成二进制数据发送。
- 服务器端代码示例
下面是服务器端代码的示例,主要是用来接收客户端发来的图片数据:
import os
import socket
import threading
import struct
# 定义服务器地址和端口号
HOST = 'localhost'
PORT = 8000
# 创建TCP套接字
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind((HOST, PORT))
server_sock.listen(10)
# 处理客户端请求的函数
def handle_client_request(client_sock, client_addr):
print('Accepted connection from {}:{}'.format(client_addr[0], client_addr[1]))
# 接收客户端发来的数据
head_fmt = '>I'
head_size = struct.calcsize(head_fmt)
head_data = client_sock.recv(head_size)
if not head_data:
print('Connection lost:', client_addr)
client_sock.close()
return
# 解析头部信息
img_len = struct.unpack(head_fmt, head_data[:head_size])[0]
img_name = struct.unpack('{}s'.format(len(head_data) - head_size), head_data[head_size:])[0].decode()
# 读取图片数据
img_data = client_sock.recv(img_len)
# 保存图片到文件
if img_data:
with open(img_name, 'wb') as f:
f.write(img_data)
print('Save {} successfully.'.format(img_name))
# 关闭套接字
client_sock.close()
# 开启服务器监听客户端请求
while True:
print('Server is waiting for connections.')
client_sock, client_addr = server_sock.accept()
t = threading.Thread(target=handle_client_request, args=(client_sock, client_addr))
t.start()
该示例代码创建了一个TCP套接字,然后进入一个循环中监听客户端的连接请求。当客户端连接成功后,服务器将为其单独启动一个线程,然后在该线程中接收客户端发送的图片数据,保存到文件中。
使用该示例程序,在服务器端会保存从客户端发送过来的test1.png
图片,图片存储位置在服务器端的工作目录下。
- 发送多张图片
如果需要发送多张图片,只需要在客户端的代码中增加一个循环即可。下面是示例代码:
import socket
import struct
# 定义服务器地址和端口号
server_addr = ('localhost', 8000)
# 定义需要发送的图片文件名列表
file_names = ['test1.png', 'test2.png']
# 创建TCP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server_addr)
# 发送图片到服务器
for file_name in file_names:
with open(file_name, 'rb') as f:
# 读取图片数据
img_data = f.read()
# 获取图片数据长度
img_len = len(img_data)
# 打包头部信息
head_fmt = '>I%ds' % len(file_name)
head_data = struct.pack(head_fmt, img_len, file_name.encode())
# 发送头部信息
sock.send(head_data)
# 发送图片数据
sock.send(img_data)
# 关闭套接字
sock.close()
该示例程序在客户端依次把需要发送的图片读入内存,然后把它们依次发送给服务器。
这就是使用Python的socket库高效传输视频数据帧(连续发送图片)的实例教程。