- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
编辑:澄清一下:它确实可以编译,但在流加载后几乎立即崩溃。 它确实连接正确。
所以,我已经尝试了很长时间来完成我的这个项目。我想做的是使用 cv2 通过套接字发送视频源。它通过 LAN 运行,而不是通过 WAN 运行。我收到以下错误:
"ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host"
客户端代码(发送视频):
import cv2
import numpy as np
import socket
import pickle
host = "<insert public ip of recipient>"
port = 7643
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # declares s object with two parameters
s.connect((host, port)) # connects to the host & port
cap = cv2.VideoCapture(1)
while cap.isOpened(): # while camera is being used
ret, frame = cap.read() # reads each frame from webcam
if ret:
encoded = pickle.dumps(cv2.imencode(".jpg", frame)[1]) # encoding each frame, instead of sending live video it is sending pictures one by one
s.sendall(encoded)
if cv2.waitKey(1) & 0xFF == ord("q"): # wait until key was pressed once and
break
cap.release()
cv2.destroyAllWindows()
接收者代码(接收视频):
import cv2
import socket
import pickle
host = "192.168.1.186"
port = 7643
boo = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # declares s object with two parameters
s.bind((host, port)) # tells my socket object to connect to this host & port "binds it to it"
s.listen(10) # tells the socket how much data it will be receiving.
conn, addr = s.accept()
while boo:
try:
pictures = conn.recv(256000) # creates a pictures variable that receives the pictures with a max amount of 128000 data it can receive
decoded = pickle.loads(pictures) # decodes the pictures
frame = cv2.imdecode(decoded, cv2.IMREAD_COLOR) # translates decoded into frames that we can see!
cv2.imshow("unique", frame)
if cv2.waitKey(1) & 0xFF == ord("q"): # wait until q key was pressed once and
break
except:
print("Something is broken...")
boo = False
cv2.destroyAllWindows()
s.close()
最佳答案
通过 LAN 运行此程序时,您显然很幸运。您的代码没有正确地将图像流从发送者发送到接收者,因为像 TCP 这样的流套接字本质上使用起来有点复杂。主要问题是您的发送方没有沟通每个图像的结束位置和下一个图像的开始位置,并且您的接收方同样没有将其读取的数据组织到单个完整图像中。
也就是说,socket.sendall()
不会将其数据的结尾传达给接收者;您需要将该信息包含在您发送的实际数据中。
但在修复此问题之前,您应该修复收件人的错误处理,以便获得更有用的错误消息。当你写的时候
except:
print("Something is broken...")
您正在丢弃一些对您有更多帮助的东西,例如“EOFError:Ran out of input”或“_pickle.UnpicklingError”。不要丢弃该信息。相反,打印它:
except:
traceback.print_exc()
或者重新加注:
except Exception as err:
# do whatever you want to do first
raise err
或者,由于您想让它使您的程序崩溃,并且只想先进行清理,因此可以在 finally
子句中进行清理,不需要 except
:
try:
# your code
finally:
# the cleanup
回到您的套接字代码,您正在使用流套接字。它们发送字节流,虽然您可以指望它们以正确的顺序到达,但您不能指望它们何时到达。如果您发送 b"something"
,然后发送 b"something else"
,您可能会同时收到 b"somethingsomething else"
,b"somet"
然后是 b"hing"
等等。您的接收者需要知道每条消息之间的分界线在哪里,因此第一步是使该分界线成为 消息之间的分界线。有几种方法可以做到这一点:
b"\n"
或 b"\n\r"
。这对于您的情况来说比较复杂。当然,如果您现在发送邮件的大小,那么这就像另一封邮件一样,并且您的收件人需要知道此大小的邮件在哪里结束。您可以再次以换行符结束大小消息:
s.sendall("{}\n".format(len(encoded)).encode("ascii"))
或者你可以将其打包成固定长度的字节数,例如 4:
s.sendall(struct.pack("!i", len(encoded)))
尽管 socket.recv()
可以返回部分消息或多条消息的一部分,但您的接收器代码现在需要读取完整消息。您可以保留传入数据的缓冲区。添加到末尾,然后从前面删除完整消息:
buf = ''
while boo:
new_data = s.recv(4096)
if not new_data:
# exit, because the socket has been closed
buf += new_data
# if there's a full message at the beginning of buf:
# remove that message, but leave the rest in buf
# process that message
# else:
# nothing, just go back to receiving more
当然,要找到完整的消息,首先您需要获取完整大小的消息。如果您使用 struct.pack
将所有大小消息编码为 4 个字节,则只需接收数据,直到 buf
的长度为 4 个或更多字节,然后将其拆分为大小和剩余的内容数据:
message_size = struct.unpack("!i", buf[:4])[0]
buf = buf[4:]
然后对图像消息执行相同的操作。接收数据,直到您拥有至少 message_size
字节的数据,将缓冲区拆分为第一条图像消息,您可以解码和显示该消息,并将其余部分保留在缓冲区中。
Warning: The
pickle
module is not secure. Only unpickle data you trust. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling. Never unpickle data that could have come from an untrusted source, or that could have been tampered with.
就您而言,理论上其他人可以在您选择的端口上连接到您的 IP,并将他们想要的任何内容发送给您的收件人。如果这只是一个玩具项目,不会一直运行,那么可能性很低。
关于Python 套接字和 Opencv - ConnectionResetError : [WinError 10054],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58784347/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!