我在传输 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。尽管如此,帖子的原始问题仍然存在。