python-发送图像槽套接字时遇到问题

问题描述 投票:1回答:1

我是python的新手,我正在尝试制作一个脚本,该脚本发送/传输笔记本电脑槽式插座的屏幕快照。如果我运行这两个脚本,则可以运行,但是在几秒钟后(我认为这是发生的情况:客户端的信息超载),它给我“修复数据被截断”错误。我一直遵循的教程仅用于发送字符串消息并使用缓冲区,但是问题是我正在使用已腌制的numpy数组,如果我对其进行缓冲,它将把第二个图像写入第一个图像并给另一个泡菜数据截断的错误,我不知道该怎么办。

感谢您的任何帮助。

服务器:

import numpy as np
import socket
import pickle
import time
import mss
import cv2
import sys

s = socket.socket()
shost = socket.gethostname()
host = socket.gethostbyname(shost) 
port = 8080
s.bind((host,port))
s.listen(5)
print(host)
print("Waiting for any incoming connections ... ")
conn, addr = s.accept()
print(addr, "Has connected to the server")

with mss.mss() as sct: #if i want it to be a different size
    monitor = {"top": 0, "left": 0, "width": 1720, "height": 720}


while True:
    img =  np.array(sct.grab(sct.monitors[1]))
    pack = pickle.dumps(img)
    conn.send(pack)
    print(sys.getsizeof(pack))

客户:

import socket
import numpy as np
import cv2
import pickle
import time


s = socket.socket()
host = input(str("Please enter the host address of the sender : "))
port = 8080
s.connect((host,port))
print("Connected ... ")

while True:
    pack = s.recv(4196540)        
    frame = pickle.loads(pack)
    cv2.imshow("Screen", frame)
    pack = ' '
    if cv2.waitKey(1) == 27:
        break

cv2.destroyAllWindows()
python sockets stream buffer screenshot
1个回答
0
投票

socket.recv()看上去相似时,如果文件类似对象,则其行为与socket.recv()不同。 “原始”套接字编程也不会为您做很多事情,这取决于您的代码来处理。

一个流套接字(.read()类型,默认情况下是使用.read()打开的那个类型)就是一个字节流,它本质上与您要通过的内容无关。要使事情变得更加复杂,例如SOCK_STREAM在评论中提到的(这与socket.socket()的相似之处可能令人困惑),其第一个参数socket.socket()并未说明您将接收多少数据,它仅限制了您准备在以下时间接收的最大数据量一次,基本上是说,我得到了这种大小的缓冲区,请给我您可以达到该大小的大小。

[如果您知道针对您的情况下的任何给定图像要接收多少数据(并且由于它们固定尺寸的屏幕截图,我想您可能很幸运),那么您需要不断重复Michael Butscher通话,直到获得完整图像为止,然后对其执行操作,然后继续进行下一个。

这意味着您可以替换:

read()

带有类似的内容:

bufsize

有更多处理方法,但是它基本上运行recv(),直到pack = s.recv(4196540) 包含item_size = 4196540 pack = b'' while len(pack) < item_size: remains = item_size - len(pack) bufsize = 4096 if remains > 4096 else remains pack += s.recv(bufsize) 个字节的数据(大概是一个腌制的图像,然后您可以继续对其进行处理。

否则,您将不得不采用其他技术:例如,您可以定义自己的协议,其中第一个recv字节是后面的文件大小,然后您知道要为下一个项出现多少数据。或为每个项目打开新连接(另一侧已关闭的套接字上的pack不会阻塞并产生4196540)。

BTW最后一条注释还意味着,在发送完最后一张图像之后,服务器可以执行n并退出(或侦听新的传入连接),并且我们可以在上面的代码段中进行另一处更改,而不是:

recv()

说:

b''

也停止在客户端接收。

© www.soinside.com 2019 - 2024. All rights reserved.