Нужна помощь с зацикливанием отправки socket Python

У меня появилась такая идея с отправкой изображений через socket сервер. Я нашел некоторую информацию в интеренете по данной теме и узнал что можно сразу преобразовать изображение в массив через numpy, а затем его уже отправить через socket. Но я не могу никак зациклить этот процесс для получения "видео". Скорее всего здесь нужна многопоточность, threading. Но я не умею эти нормально пользоваться( Поэтому все мои попытки зациклить отправку не увенчались успехом... Пожалуйста подскажите как это можно реализовать?

Сервер:

import socket, pickle
import time
import cv2
import mss
import numpy

HOST = 'localhost'
s = socket.socket()
s.bind((HOST, 9090))
s.listen(1)
while True:
    conn, addr = s.accept()
    print ('Connected by', addr)
    all_data = bytearray()
    while True:
        data = conn.recv(4096)
        if not data: 
            break
        all_data += data
    obj = pickle.loads(all_data)
    print(obj)
    for _ in range(100000000):
        cv2.imshow('VIDEO', obj)
        cv2.waitKey(20)
conn.close()

Клиент:

import socket, pickle
import time
import cv2
import mss
import numpy

HOST = 'localhost'

s = socket.socket()
s.connect((HOST, 9090))

with mss.mss() as sct:
    monitor = {'top': 0, 'left': 0, 'width': 1920, 'height': 1080}
    img = numpy.array(sct.grab(monitor))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    print(img)

data = pickle.dumps(img)
s.sendall(data)
s.close()

Ответы (1 шт):

Автор решения: Roman Konoval

Несколько важных вещей, которые пригодятся для того чтобы сделать то, что нужно:

  1. использовать запись и чтение из файла вместо строки. Это позволит писать/читать поток pickle-представлений и не придумывать свой способ как определять, конец одного изображения и начало другого.
  2. функция makefile у объекта сокет, которая позволяет сделать обертку над сокетом, чтобы можно было использовать пункт 1

Я тут пишу схему самых важных частей сервера и клиента (я не запускал и не тестировал этот код).

Сервер:

while True:
    conn, addr = s.accept()
    print ('Connected by', addr)
     # используем binary режим. В зависимости от версии pickle, которая в свою очередь
     # зависит от версии питона, может потребоваться убрать этот параметр
    socket_file = conn.makefile('b')
    try:
        while True:
            obj = pickle.load(socket_file)
            cv2.imshow('VIDEO', obj)
    except EOFError:
        pass
conn.close()

Клиент:

s.connect((HOST, 9090))

# w - указывает, что файл открываем на запись в binary режиме
socket_file = s.makefile('wb')

while True:
    with mss.mss() as sct:
        monitor = {'top': 0, 'left': 0, 'width': 1920, 'height': 1080}
        img = numpy.array(sct.grab(monitor))
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        print(img)
        pickle.dump(img, socket_file)

s.close()

Обратите внимание, что я убрал цикл при показе изображения. Я так понимаю он нужен был чтобы программа не закрывалась, а здесь он не нужен, так как мы ожидаем новое изображение.

→ Ссылка