Python-UDP屏幕共享
我的UDP屏幕截图传输有问题。我正在尝试通过UDP套接字不断传输屏幕截图,以便在另一端显示它们(客户端发送图像,服务器显示图像)。我已经用TCP实现了,但是用UDP实现也不错 代码: 服务器端Python-UDP屏幕共享,python,sockets,udp,client-server,screensharing,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(
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()
导入套接字
导入线程
从zlib导入解压缩
导入pygame
宽度=1900
高度=1000
主机='192.168.1.42'
端口=5000
def统一像素(lst):
数据=“”
对于范围(0,10)内的i:
data=data+string.from_字节(lst.pop(0),byteorder='big')
bytedata=字节(数据“utf-8”)
返回字节数据
def recvall(UDPServerSocket,长度):
“”“检索所有像素。”“”
buf=b''
而len(buf)<长度:
data=UDPServerSocket.recvfrom(长度-长度(buf))
如果没有数据:
返回数据
buf+=数据
返回buf
def屏幕共享(conn):
像素_lst=[]#字节块列表
pygame.init()
screen=pygame.display.set_模式((950500))
clock=pygame.time.clock()
观看=真实
观看时:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
监视=错误
打破
#检索像素长度、像素长度和像素的大小
size\u len=int.from\u字节(conn.recvfrom(1024),byteorder='big')
size=int.from_字节(recvall(conn,size_len),byteorder='big')
对于范围(1,11)内的i:
像素附加(conn.recvfrom(大小))
像素=解压缩(重新统一像素(像素),6)
#从原始像素创建曲面
img=pygame.image.fromstring(像素,(宽度,高度),'RGB')
#显示图片
屏幕blit(img,(0,0))
pygame.display.flip()
时钟滴答(60)
def main():
UDPServerSocket=socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)
绑定((主机,端口))
尝试:
打印('服务器已启动')
thread=threading.thread(target=ScreenShare,args=(UDPServerSocket,))
thread.start()
最后:
UDPServerSocket.close()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
客户端
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()
导入套接字
进口zlib
导入mss
宽度=1900
高度=1000
主机='192.168.1.42'
端口=5000
LocalHost=((主机,端口))
def split_img(seq,chunk,skip_tail=False):
lst=[]
如果你对这段代码的问题是什么?让我澄清一下会发生什么-pygame窗口本应显示的照片只是冻结和折叠。我的问题是如何分割压缩的图像,然后重新连接,而不使其出错,我想我在服务器端看到的一个大问题是,您正在无限地使用ScreenShare
实例创建新线程,这可能最终导致应用程序崩溃。您的意思是什么?我在使用TCP时保持了相同的结构,这很好。顺便说一句,我想我发现了一些问题-似乎我用utf-8解码压缩字节是。。。非法的。所以我需要找到一些其他的方法,当它们是一个字节时,把它们像字符串一样加起来。