使用 ZMQ 时,从 Ubuntu 16.04 到 Windows 7 的出站 TCP 流量被阻止
Outbound TCP Traffic From Ubuntu 16.04 to Windows 7 is blocked when using ZMQ
我在服务器和客户端之间有一个用 Python 编写的 ZeroMQ PUB/SUB
连接。服务端发送消息,客户端打印出来
这些程序在同一台计算机上工作得很好(Ubuntu 16.04,或 Windows 7;两者都工作)。
当服务器在 Windows 7 机器上并且客户端在 Ubuntu 16.04 机器上时,它们也可以工作。
但是,如果服务器在 Ubuntu 16.04 机器上,那么 Windows 7 机器上的客户端无法连接到它。
此外,当我在两台单独的 Windows 7 台机器之间移动客户端和服务器程序时,通信没有问题。
有人知道问题出在哪里吗?
这里是客户端代码:
#Based on code found on this Stack Overflow post:
#
import cv2
import zmq
import base64
import numpy as np
context = zmq.Context()
footage_socket = context.socket(zmq.SUB)
address = 'tcp://192.168.128.229:5555'
footage_socket.connect(address)
footage_socket.setsockopt_string(zmq.SUBSCRIBE, unicode(''))
print "start"
print "connecting to ", address
while True:
try:
frame = footage_socket.recv_string()
img = base64.b64decode(frame)
npimg = np.fromstring(img, dtype=np.uint8)
source = cv2.imdecode(npimg, 1)
cv2.imshow("image", source)
cv2.waitKey(1)
except KeyboardInterrupt:
cv2.destroyAllWindows()
print "\n\nBye bye\n"
break
这是服务器代码:
#Based on code found on this Stack Overflow post:
#
import cv2
import zmq
import base64
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.bind('tcp://*:5555')
footage_socket.setsockopt(zmq.CONFLATE, 1)
camera = cv2.VideoCapture(0)
while True:
try:
(grabbed, frame) = camera.read()
frame = cv2.resize(frame, (640, 480))
encoded, buffer = cv2.imencode('.png', frame)
footage_socket.send_string(base64.b64encode(buffer))
except KeyboardInterrupt:
camera.release()
cv2.destroyAllWindows()
print "\n\nBye bye\n"
break
最佳实践列表:
- 解读:不靠重装成
string
-wrapped原创内容(已经发了很多string
在 post Python-3.0+ ) 中成为 byte
后的问题
- 版本控制:并非所有版本的 ZeroMQ 核心设施都具有相同的作案手法(
PUB/SUB
主题过滤发生在 PUB
在最近的版本中,而在 ZeroMQ 早期的 SUB
方面进行操作。版本很重要.
性能: 尽可能避免核心数据流的开销 "external"。使用 base64.{b64encode()|b64decode()}
是这种不利的性能舒适度的一个例子,没有提供任何足够的好处。
剖析、调整和检查任何基于 cv2
的帧处理的实际成本 ~ colour-space 转换可能需要 +170 [ms] p.i。 (在左下 window )
可以以一种非常廉价的方式将任何进一步的细节添加到 aMessagePAYLOAD 中(通过 struct.pack( aPayloadMASK, .data, OptionA, OptionB, OptionC )
- 无论是旋转 aSeqNumUINT8, aUsecTimeSTAMP
,还是任何其他人可能想添加的内容)
做-s PUB
-side:
import numpy as np
import zmq
import cv2
import struct
print( "INF: this process uses {0: >10s} v.{1:}".format( "ZMQ", zmq.__version__ ) )
print( "INF: this process uses {0: >10s} v.{1:}".format( "NUMPY", np.__version__ ) )
...
..
aPubSOCKET.setsockopt( zmq.LINGER, 0 )
aPubSOCKET.setsockopt( zmq.IMMEDIATE, 1 )
aPubSOCKET.setsockopt( zmq.TOS, aTypeOfSERVICE_PREFERENCE_ID )
aPubSOCKET.setsockopt( zmq.SNDHWM, 4 )
aPubSOCKET.setsockopt( zmq.SNDBUF, 4*640*480*3 )
aPubSOCKET.setsockopt( zmq.CONFLATE, 1 )
...
..
.
aPayloadMAP = ">"+ ( 640 * 480 * 3 )*"B"
HiResCAM = cv2.VideoCapture( 0 )
while True:
try:
( _ , cv2HiResFRAME ) = HiResCAM.read() # acquire FRAME
aPubSOCKET.send( struct.pack( aPayloadMAP, # pack to aMsgPAYLOAD, once .resize()'d
cv2.resize( cv2HiResFRAME,
( 640, 480 )
).data
), # OpenCV 2.2+ natively uses numpy arrays W * H * D * unit8 in BGR-ordering ( BGRA, if alpha used )
zmq.NOBLOCK
)
except KeyboardInterrupt:
# ...
finally:
# gracefully terminate all OpenCV resources
# gracefully terminate all ZeroMQ resources
break
做-s SUB
-边:
import numpy as np
import zmq
import cv2
import struct
print( "INF: this process uses {0: >10s} v.{1:}".format( "ZMQ", zmq.__version__ ) )
print( "INF: this process uses {0: >10s} v.{1:}".format( "NUMPY", np.__version__ ) )
...
..
aSubSOCKET.setsockopt( zmq.LINGER, 0 )
aSubSOCKET.setsockopt( zmq.CONFLATE, 1 )
aSubSOCKET.setsockopt( zmq.MAXMSGSIZE, 100+640*480*3 )
aSubSOCKET.setsockopt( zmq.RCVHWM, 4 )
aSubSOCKET.setsockopt( zmq.RCVBUF, 4*640*480*3 )
aSubSOCKET.connect( address )
aSubSOCKET.setsockopt( zmq.SUBSCRIBE, "" )
aPayloadMASK = ">" + ( 640 * 480 * 3 * "B" )
while True:
try:
cv2.imshow( "LAST IMAGERY AVAILABLE:", struct.decode( aPayloadMASK, aSubSOCKET.recv() )
cv2.waitKey( 1 )
except KeyboardInterrupt:
# ...
finally:
# gracefully terminate all OpenCV resources
# gracefully terminate all ZeroMQ resources
break
我在服务器和客户端之间有一个用 Python 编写的 ZeroMQ PUB/SUB
连接。服务端发送消息,客户端打印出来
这些程序在同一台计算机上工作得很好(Ubuntu 16.04,或 Windows 7;两者都工作)。
当服务器在 Windows 7 机器上并且客户端在 Ubuntu 16.04 机器上时,它们也可以工作。
但是,如果服务器在 Ubuntu 16.04 机器上,那么 Windows 7 机器上的客户端无法连接到它。
此外,当我在两台单独的 Windows 7 台机器之间移动客户端和服务器程序时,通信没有问题。
有人知道问题出在哪里吗?
这里是客户端代码:
#Based on code found on this Stack Overflow post:
#
import cv2
import zmq
import base64
import numpy as np
context = zmq.Context()
footage_socket = context.socket(zmq.SUB)
address = 'tcp://192.168.128.229:5555'
footage_socket.connect(address)
footage_socket.setsockopt_string(zmq.SUBSCRIBE, unicode(''))
print "start"
print "connecting to ", address
while True:
try:
frame = footage_socket.recv_string()
img = base64.b64decode(frame)
npimg = np.fromstring(img, dtype=np.uint8)
source = cv2.imdecode(npimg, 1)
cv2.imshow("image", source)
cv2.waitKey(1)
except KeyboardInterrupt:
cv2.destroyAllWindows()
print "\n\nBye bye\n"
break
这是服务器代码:
#Based on code found on this Stack Overflow post:
#
import cv2
import zmq
import base64
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.bind('tcp://*:5555')
footage_socket.setsockopt(zmq.CONFLATE, 1)
camera = cv2.VideoCapture(0)
while True:
try:
(grabbed, frame) = camera.read()
frame = cv2.resize(frame, (640, 480))
encoded, buffer = cv2.imencode('.png', frame)
footage_socket.send_string(base64.b64encode(buffer))
except KeyboardInterrupt:
camera.release()
cv2.destroyAllWindows()
print "\n\nBye bye\n"
break
最佳实践列表:
- 解读:不靠重装成
string
-wrapped原创内容(已经发了很多string
在 post Python-3.0+ ) 中成为 - 版本控制:并非所有版本的 ZeroMQ 核心设施都具有相同的作案手法(
PUB/SUB
主题过滤发生在PUB
在最近的版本中,而在 ZeroMQ 早期的SUB
方面进行操作。版本很重要. 性能: 尽可能避免核心数据流的开销 "external"。使用
base64.{b64encode()|b64decode()}
是这种不利的性能舒适度的一个例子,没有提供任何足够的好处。剖析、调整和检查任何基于
cv2
的帧处理的实际成本 ~ colour-space 转换可能需要 +170 [ms] p.i。 (在左下 window )可以以一种非常廉价的方式将任何进一步的细节添加到 aMessagePAYLOAD 中(通过
struct.pack( aPayloadMASK, .data, OptionA, OptionB, OptionC )
- 无论是旋转aSeqNumUINT8, aUsecTimeSTAMP
,还是任何其他人可能想添加的内容)
byte
后的问题
做-s PUB
-side:
import numpy as np
import zmq
import cv2
import struct
print( "INF: this process uses {0: >10s} v.{1:}".format( "ZMQ", zmq.__version__ ) )
print( "INF: this process uses {0: >10s} v.{1:}".format( "NUMPY", np.__version__ ) )
...
..
aPubSOCKET.setsockopt( zmq.LINGER, 0 )
aPubSOCKET.setsockopt( zmq.IMMEDIATE, 1 )
aPubSOCKET.setsockopt( zmq.TOS, aTypeOfSERVICE_PREFERENCE_ID )
aPubSOCKET.setsockopt( zmq.SNDHWM, 4 )
aPubSOCKET.setsockopt( zmq.SNDBUF, 4*640*480*3 )
aPubSOCKET.setsockopt( zmq.CONFLATE, 1 )
...
..
.
aPayloadMAP = ">"+ ( 640 * 480 * 3 )*"B"
HiResCAM = cv2.VideoCapture( 0 )
while True:
try:
( _ , cv2HiResFRAME ) = HiResCAM.read() # acquire FRAME
aPubSOCKET.send( struct.pack( aPayloadMAP, # pack to aMsgPAYLOAD, once .resize()'d
cv2.resize( cv2HiResFRAME,
( 640, 480 )
).data
), # OpenCV 2.2+ natively uses numpy arrays W * H * D * unit8 in BGR-ordering ( BGRA, if alpha used )
zmq.NOBLOCK
)
except KeyboardInterrupt:
# ...
finally:
# gracefully terminate all OpenCV resources
# gracefully terminate all ZeroMQ resources
break
做-s SUB
-边:
import numpy as np
import zmq
import cv2
import struct
print( "INF: this process uses {0: >10s} v.{1:}".format( "ZMQ", zmq.__version__ ) )
print( "INF: this process uses {0: >10s} v.{1:}".format( "NUMPY", np.__version__ ) )
...
..
aSubSOCKET.setsockopt( zmq.LINGER, 0 )
aSubSOCKET.setsockopt( zmq.CONFLATE, 1 )
aSubSOCKET.setsockopt( zmq.MAXMSGSIZE, 100+640*480*3 )
aSubSOCKET.setsockopt( zmq.RCVHWM, 4 )
aSubSOCKET.setsockopt( zmq.RCVBUF, 4*640*480*3 )
aSubSOCKET.connect( address )
aSubSOCKET.setsockopt( zmq.SUBSCRIBE, "" )
aPayloadMASK = ">" + ( 640 * 480 * 3 * "B" )
while True:
try:
cv2.imshow( "LAST IMAGERY AVAILABLE:", struct.decode( aPayloadMASK, aSubSOCKET.recv() )
cv2.waitKey( 1 )
except KeyboardInterrupt:
# ...
finally:
# gracefully terminate all OpenCV resources
# gracefully terminate all ZeroMQ resources
break