Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python-在通过套接字发送图像时遇到问题_Python_Sockets_Stream_Buffer_Screenshot - Fatal编程技术网

python-在通过套接字发送图像时遇到问题

python-在通过套接字发送图像时遇到问题,python,sockets,stream,buffer,screenshot,Python,Sockets,Stream,Buffer,Screenshot,我是python新手,我正在尝试制作一个脚本,用于发送/流式传输我的笔记本电脑插槽的屏幕截图。如果我运行这两个脚本,它会工作,但几秒钟后(我认为这就是发生的情况:客户机信息过载),它会给我“pickle data was truncated”错误。我所遵循的教程只用于发送字符串消息和使用缓冲区,但问题是我使用的是一个经过pickle处理的numpy数组,如果我对它进行缓冲,它会将第二个图像写入第一个图像,并给出另一个pickle数据截断错误,我不知道该怎么办 感谢您的帮助 服务器: import

我是python新手,我正在尝试制作一个脚本,用于发送/流式传输我的笔记本电脑插槽的屏幕截图。如果我运行这两个脚本,它会工作,但几秒钟后(我认为这就是发生的情况:客户机信息过载),它会给我“pickle data was truncated”错误。我所遵循的教程只用于发送字符串消息和使用缓冲区,但问题是我使用的是一个经过pickle处理的
numpy
数组,如果我对它进行缓冲,它会将第二个图像写入第一个图像,并给出另一个pickle数据截断错误,我不知道该怎么办

感谢您的帮助

服务器:

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()
虽然看起来很相似,但其行为方式与类似文件的对象不同。“原始”套接字编程也并没有为您做很多内务处理,这取决于您的代码来处理它

流套接字(
SOCK\u stream
类型是默认打开的类型,它只是一个字节流,它本质上与您通过它的内容无关。为了使事情更复杂,正如注释中所提到的(这就是与
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)
说:

停止客户端的接收

还有一个关于您提到的教程的注意事项。在一些琐碎的情况下,例如发送短字符串消息,虽然您不应该依赖它,但您通常会幸运地将所有预期数据都记录在一个块中。

虽然看起来很相似,但其行为方式与类似文件的对象不同。“Raw”socket编程也并没有为您做很多内务处理,这取决于您的代码来处理它

流套接字(
SOCK\u stream
类型是默认打开的类型,它只是一个字节流,它本质上与您通过它的内容无关。为了使事情更复杂,正如注释中所提到的(这就是与
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)
说:

停止客户端的接收


还有一个关于您提到的教程的注意事项。在一些琐碎的情况下,例如发送短字符串消息,虽然您不应该依赖它,但您通常会幸运地在一块中接收到所有预期数据。

“接收”最多返回作为参数给定的字节数,但返回的字节数可能较少,您必须从多个调用中收集数据,直到获得所有数据。@MichaelButscher抱歉,我不太明白,所以我需要多次接收还是需要将图像分为多个部分发送?“接收”必须多次调用。您还必须相应地更改其大小参数,否则您可能会收到属于下一个图像的数据。“recv”最多返回作为参数给定的字节数,但返回的字节数可能较少,您必须从多个调用中收集数据,直到获得所有数据。@MichaelButscher抱歉,我不太明白,所以我需要多次接收还是需要将图像分为多个部分发送?“接收”必须多次调用。您还必须相应地更改其大小参数,否则您可能会收到属于下一个图像的数据。