Python - UDP 屏幕共享

时间:2021-04-20 19:51:40

标签: python sockets udp client-server screensharing

我在传输 UDP 屏幕截图时遇到问题。我正在尝试通过 UDP 套接字不断传输屏幕截图以在另一侧显示它们(客户端发送图像,服务器显示它们)。我已经通过 TCP 实现了它,但是在 UDP 中使用它也很好。

代码: 服务器端

import socket
import threading
from zlib import decompress

import pygame

WIDTH = 1900
HEIGHT = 1000
host = '192.168.1.42'
port=5000

def reunitepixels(lst):
    data = ''
    for i in range(0,10):
        data =data + string.from_bytes(lst.pop(0), byteorder = 'big')
    bytedata = bytes(data, 'utf-8')
    return bytedata

def recvall(UDPServerSocket, length):
    
    """ Retreive all pixels. """

    buf = b''
    while len(buf) < length:
        data = UDPServerSocket.recvfrom(length - len(buf))
        if not data:
            return data
        buf += data
    return buf

def ScreenShare(conn):
    pixels_lst =[] #list of byte chunks 
    pygame.init()
    screen = pygame.display.set_mode((950, 500))
    clock = pygame.time.Clock()
    watching = True
    while watching:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    watching = False
                    break
        # Retreive the size of the pixels length, the pixels length and pixels
        size_len = int.from_bytes(conn.recvfrom(1024), byteorder='big')
        size = int.from_bytes(recvall(conn, size_len), byteorder='big')
        for i in range(1,11):
            pixels_lst.append(conn.recvfrom(size))
        pixels = decompress(reunitepixels(pixels_lst), 6)
        # Create the Surface from raw pixels
        img = pygame.image.fromstring(pixels, (WIDTH, HEIGHT), 'RGB')
        # Display the picture
        screen.blit(img, (0, 0))
        pygame.display.flip()
        clock.tick(60)
def main():
    UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    UDPServerSocket.bind((host, port))
    try:
        print('Server started.')
        thread = threading.Thread(target=ScreenShare, args=(UDPServerSocket,))
        thread.start()
    finally:
        UDPServerSocket.close()


if __name__ == '__main__':
    main()

客户端

import socket
import zlib

import mss

WIDTH = 1900
HEIGHT = 1000
host = '192.168.1.42'
port=5000

LocalHost = ((host,port))

def split_img(seq, chunk, skip_tail=False):
    lst = []
    if chunk <= len(seq):
        lst.extend([seq[:chunk]])
        lst.extend(split_img(seq[chunk:], chunk, skip_tail))
    elif not skip_tail and seq:
        lst.extend([seq])
    return lst

def retreive_screenshot(sock):
    with mss.mss() as sct:
        # The region to capture
        rect = {'top': 0, 'left': 0, 'width': WIDTH, 'height': HEIGHT}

        while True:
            sliced_image = []
            img = sct.grab(rect)
            pixels = zlib.compress(img.rgb, 6)
            sliced_image = split_img(pixels,int(len(pixels)/10))
            break
            size = len(pixels)
            size_len = (size.bit_length() + 7) // 8
            sock.sendto(bytes([size_len]), LocalHost)

            # Send the actual pixels length
            size_bytes = size.to_bytes(size_len, 'big')
            sock.sendto(size_bytes, LocalHost)
            # Send pixels
            for i in sliced_image:
                sock.sendto(sliced_image.pop(0), LocalHost)

def main():
    watching = True    

    UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
    try:
        while 'connected':
            retreive_screenshot(UDPClientSocket)
    finally:
        UDPClientSocket.close()


if __name__ == '__main__':
    main()

我正在尝试将客户端的压缩字节变量“像素”拆分为多个块,然后将每个块发送到服务器端,服务器端会将它们“修复”在一起并形成完整的屏幕截图。

更新 我在发帖后看到我有一些以前从未见过的明显问题,因为它几乎立即崩溃了,因此它从未达到线程的功能。以上是最新的代码,它给出了错误 10038,我正在尝试修复 atm。尽管如此,帖子的原始问题仍然存在。

0 个答案:

没有答案