近期准备做人脸识别的项目,需要将本地拍摄的图片传递到服务器,检测完在传回来,正在学习Socket相关知识,将今日所学知识分享,有大佬有更好的方法随时在博客下交流!共勉
要注意一点,先运行Server.py,在运行Client.py。host换成你自己的ip地址,有服务器的填服务器的ip地址,这里我就不写出来了hhh
Client.py
import socket
import time
import cv2
from loguru import logger
class client_socket(object):
def __init__(self, host='172.16.2.XXX', port=9999, status='send'):
self.hp = (host, port)
self.c_socket = self.generate()
print("Client socket connect successfully")
self.host = host
self.port = port
if status == 'listen':
self.recv_info()
elif status == 'send':
# test_info = input("请输入你要给服务端发送的test话语")
# self.send_msg(test_info)
image_path = input('请输入要传输的图像地址')
self.send_image(image_path)
def generate(self):
csk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
csk.connect(self.hp)
return csk
def recv_info(self):
self.c_socket.bind(self.hp)
self.c_socket.listen(5)
logger.info(f'client_socket is listening to {self.host}: {self.port}...')
def send_msg(self,msg):
start_time = time.time()
self.c_socket.sendall(msg.encode('utf-8'))
end_time = time.time()
logger.info(f'client_socket is sending...')
logger.info(f'sending msg time is {end_time - start_time}')
def send_image(self,image):
"""
:param image: 要经过编码处理
:return: None
"""
image_data = self.get_image(image)
self.c_socket.send(image_data)
print("successfully sent image")
@classmethod
def image_encode(cls,image,encode_way='base64'):
# 默认为BASE64编码方式
if encode_way == 'base64':
import base64
_ , encode_image = cv2.imencode('.jpg',image)
image_bytes = encode_image.tobytes()
image_base64 = base64.b64encode(image_bytes).decode('utf-8')
return image_base64
else:
# TODO:实践中若有其他需求可以另写在这,这里只提供base64编码方式
pass
def get_image(self,img):
image = cv2.imread(img)
image_b = self.image_encode(image)
image_d = image_b.encode('utf-8')
return image_d
def close(self):
self.c_socket.close()
print("socket Close")
def Main():
cs = client_socket()
cs.close()
if __name__ == '__main__':
# import cProfile
# cProfile.run('Main()')
Main()
Server.py
import os
from socket import *
import base64
# 图片解码
def base64_to_image_data(base64_string):
"""
将 Base64 编码的字符串转换为图像二进制数据。
"""
image_bytes = base64.b64decode(base64_string)
return image_bytes
class ImageServer:
def __init__(self, ip="172.16.2.143", port_number=9999):
self.socket_connection = socket()
self.ip_address = ip
self.port = port_number
def start_listening(self):
"""开始监听指定端口"""
self.socket_connection.bind((self.ip_address, self.port))
self.socket_connection.listen() # 设置为监听状态
def accept_connections(self):
"""接受客户端连接"""
while True:
print("等待连接...")
connection, client_address = self.socket_connection.accept()
print(f"连接到: {client_address[0]}\t端口: {client_address[1]}")
return connection, client_address
def close_server(self):
"""关闭服务器"""
self.socket_connection.close()
class ImageConnectionHandler:
def __init__(self, connection, client_address):
self.connection = connection
self.client_address = client_address
self.image_storage_path = "received_images/"
self.is_receiving = False
def close(self):
"""关闭与客户端的连接"""
self.connection.close()
print(f"{self.client_address[0]}:{self.client_address[1]} 已断开连接")
def send(self, text_message):
"""向客户端发送消息"""
self.connection.send(text_message.encode())
def receive(self, buffer_size=1024):
"""从客户端接收消息"""
data = self.connection.recv(buffer_size).decode()
return data
def process_image_data(self, image_data_count):
if not os.path.exists(self.image_storage_path):
os.makedirs(self.image_storage_path)
image_bytes = b"" # 存储接收到的图像数据
while True:
current_data = self.receive()
if current_data:
image_bytes += current_data.encode()
else:
self.is_receiving = True
break
image_data = base64_to_image_data(image_bytes)
file_path = f"{self.image_storage_path}/{image_data_count}.jpg"
with open(file_path, "wb") as image_file:
image_file.write(image_data)
if __name__ == '__main__':
server = ImageServer()
server.start_listening()
image_counter = 0
while True:
connection, client_address = server.accept_connections()
handler = ImageConnectionHandler(connection, client_address)
while True:
handler.process_image_data(image_counter)
image_counter += 1
print(f"图像 {image_counter} 处理完成")
if handler.is_receiving:
break