Я создаю клиент-серверное приложение, которое передает данные экрана с клиента на сервер с помощью Python, OpenCV и сокетов. Потоковая передача экрана осуществляется путем захвата снимка экрана на клиенте, его кодирования в формате JPEG и отправки на сервер. Сервер декодирует изображение и отображает его с помощью OpenCV.
Однако, когда я запускаю приложение, сервер получает что-то вроде тарабарщины или поврежденных данных, что в конечном итоге приводит к сбою сервера. Похоже, проблема возникает при получении данных изображения, что приводит к отображению неполных или поврежденных изображений.
Вот что я пробовал:
Using a helper function recv_all() to ensure the full image data is received before decoding.
The client sends the image size first, followed by the actual image data.
Both client and server use a loop to ensure they receive all the data before processing it.
Несмотря на эти усилия, я по-прежнему вижу мусорные или поврежденные данные, и в конечном итоге сервер выходит из строя.
server.py
import socket
import threading
import cv2
import numpy as np
from file_management import receive_file, send_file, execute_file
SERVER_IP = '192.168.68.117'
SERVER_PORT = 60608
def recv_all(conn, size):
data = b''
while len(data) < size:
try:
chunk = conn.recv(4096)
if not chunk:
break
data += chunk
except socket.error:
conn.close()
break
return data
def handle_client(conn, addr):
print(f"Connected to {addr}")
try:
while True:
command = conn.recv(1024).decode(errors='ignore')
if not command:
print(f"Connection closed by {addr}")
break
print(f"Received command: {command}")
if command.startswith("upload"):
filename = command.split(" ")[1]
receive_file(conn, filename)
elif command.startswith("download"):
filepath = command.split(" ")[1]
send_file(conn, filepath)
elif command.startswith("execute"):
filepath = command.split(" ")[1]
execute_file(conn, filepath)
elif command.startswith("screen"):
screen_size_bytes = conn.recv(4)
if not screen_size_bytes:
print(f"Connection closed by {addr}")
break
screen_size = int.from_bytes(screen_size_bytes, 'big')
screen_data = recv_all(conn, screen_size)
if screen_data:
np_img = np.frombuffer(screen_data, dtype=np.uint8)
img = cv2.imdecode(np_img, cv2.IMREAD_COLOR)
if img is not None:
cv2.imshow(f"Remote Desktop - {addr}", img)
cv2.waitKey(1)
print(f"Client {addr} has disconnected.")
except Exception as e:
print(f"Error while handling client {addr}: {str(e)}")
finally:
conn.close()
print(f"Connection closed for {addr}")
def start_remote_desktop_server():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((SERVER_IP, SERVER_PORT))
server.listen(1)
print(f"Remote Desktop Server listening on {SERVER_IP}:{SERVER_PORT}...")
while True:
try:
conn, addr = server.accept()
print(f"Accepted connection from {addr}")
client_thread = threading.Thread(target=handle_client, args=(conn, addr))
client_thread.start()
except Exception as e:
print(f"Error accepting connection: {str(e)}")
if __name__ == "__main__":
start_remote_desktop_server()
client.py
import socket
import threading
import cv2
import numpy as np
import pyautogui
from file_management import upload_file, download_file, execute_remote_file
SERVER_IP = '192.168.68.117'
SERVER_PORT = 60608
def send_screen(conn):
while True:
try:
screenshot = pyautogui.screenshot()
img_np = np.array(screenshot)
_, img_encoded = cv2.imencode('.jpg', img_np)
img_data = img_encoded.tobytes()
conn.send(len(img_data).to_bytes(4, 'big'))
conn.sendall(img_data)
cv2.waitKey(1)
except Exception as e:
print(f"Error sending screen data: {str(e)}")
break
def recv_all(conn, size):
data = b''
while len(data) < size:
try:
chunk = conn.recv(4096)
if not chunk:
break
data += chunk
except socket.error:
conn.close()
break
return data
def handle_commands(conn):
while True:
command = input("\n \n > ")
if command.startswith("upload"):
filepath = command.split(" ")[1]
upload_file(conn, filepath)
elif command.startswith("download"):
filename = command.split(" ")[1]
download_file(conn, filename)
elif command.startswith("execute"):
filepath = command.split(" ")[1]
try:
execute_remote_file(conn, filepath)
except ConnectionResetError:
print("Connection lost. The server may have closed the connection.")
break
except Exception as e:
print(f"Error executing file remotely: {str(e)}")
elif command == "exit":
print("Exiting...")
break
else:
print("Invalid command. Use upload, download, execute, or exit.")
def start_client():
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
conn.connect((SERVER_IP, SERVER_PORT))
print(f"Connected to {SERVER_IP}:{SERVER_PORT}")
threading.Thread(target=send_screen, args=(conn,), daemon=True).start()
handle_commands(conn)
except OSError as e:
print(f"Failed to connect to server: {str(e)}")
except Exception as e:
print(f"An unexpected error occurred: {str(e)}")
finally:
try:
conn.close()
print("Connection closed.")
except OSError as e:
print(f"Error closing connection: {str(e)}")
if __name__ == "__main__":
start_client()
Подробнее здесь: https://stackoverflow.com/questions/791 ... aming-open
Сбой клиент-серверного приложения из-за тарабарщины данных при потоковой передаче экрана (OpenCV, сокеты) ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
ОШИБКА веб-стриминга из OpenCV при потоковой передаче с помощью flask в Raspberry Pi
Anonymous » » в форуме Python - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Ошибка выключения экрана при потоковой передаче видео на веб -сайте фильма использует ReactJS
Anonymous » » в форуме IOS - 0 Ответы
- 33 Просмотры
-
Последнее сообщение Anonymous
-