我想在机器之间建立发布订阅通信。
我拥有的两台计算机是ryu-primary
和ryu-secondary
我在每台机器中遵循的步骤如下:
在ryu-primary
的初始值设定项中(IP地址为192.168.241.131)
self.context = zmq.Context()
self.sub_socket = self.context.socket(zmq.SUB)
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_port = 5566
self.sub_port = 5566
def establish_zmq_connection(self): # Socket to talk to server
print( "Connection to ryu-secondary..." )
self.sub_socket.connect( "tcp://192.168.241.132:%s" % self.sub_port )
def listen_zmq_connection(self):
print( 'Listen to zmq connection' )
self.pub_socket.bind( "tcp://*:%s" % self.pub_port )
def recieve_messages(self):
while True:
try:
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
print( 'flow mod messages recieved {}'.format(string) )
return string
except zmq.ZMQError:
break
def push_messages(self,msg):
self.pub_socket.send( "%s" % (msg) )
来自ryu-secondary(IP地址 - 192.168.241.132)
在初始化程序中
self.context = zmq.Context()
self.sub_socket = self.context.socket(zmq.SUB)
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_port = 5566
self.sub_port = 5566
def establish_zmq_connection(self): # Socket to talk to server
print( "Connection to ryu-secondary..." )
self.sub_socket.connect( "tcp://192.168.241.131:%s" % self.sub_port )
def listen_zmq_connection(self):
print( 'Listen to zmq connection' )
self.pub_socket.bind( "tcp://*:%s" % self.pub_port )
def recieve_messages(self):
while True:
try:
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
print( 'flow mod messages recieved {}'.format(string) )
return string
except zmq.ZMQError:
break
def push_messages(self,msg):
print( 'pushing message to publish socket' )
self.pub_socket.send( "%s" % (msg) )
这些是我的功能。
我正在呼叫ryu-secondary
:
establish_zmq_connections()
push_messages()
在ryu-primary
时,我打电话
listen_zmq_connection()
recieve_messages()
使用 .setsockopt( zmq.SUBSCRIBE = '')
订阅所有类型的邮件之后
但是我尝试发送的消息属于以下类型。
msg = {'in_port':in_port,'dst':dst,'actions':actions}
self.push_messages(msg)
然而另一方面(recieve_messages()
我在执行此操作时出现以下错误
flow_mod = recieve_messages()
flow_mod['in_port']
flow_mod['dst']
flow_mod['actions']
TypeError: string indices must be integers, not str
答案 0 :(得分:1)
msg
是一个Python dict,但是你发送(和接收)格式化为字符串的消息。可能最简单的方法是将msg
序列化为JSON格式,将其作为字符串发送,然后再将接收到的字符串重新加载到dict中。然后,只有这样,您才能正确访问键和值。这样的事情应该有用(确保你import json
在上面某处):
# on the sending end
msg = {'in_port':in_port,'dst':dst,'actions':actions}
msg_string = json.dumps(msg)
self.push_messages(msg)
# on the receiving end
payload = receive_messages()
message = json.loads(payload)
您可以找到json
模块here(适用于Python 2)和{3}}适用于Python 3的完整文档。
答案 1 :(得分:0)
ZeroMQ .send()
.recv()
方法对字符串进行操作。您向他们传递了一个他们不知道如何处理的字典对象。将字典对象转换为JSON格式,作为针对这种情况的序列化示例,您的工作已经完成。
正如写的那样,ZeroMQ的.send()
方法在发送它不理解的对象方面做得不多,而.recv()部分仍然可以读取ZeroMQ层上传递的任何内容。
因此,您的 flow_mod
变量正确地在函数字符串作为 return string
指令> recieve_messages()
订单。
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
只是提供任何字符串,无论是空字符串还是从套接字的另一端收到的任何非零长度字符串。
<强>最后:强>
flow_mod['in_port']
会语法崩溃(并且必须这样做),因为变量flow_mod
的内容已分配给&amp;在此之前进行类型调整,没有类似于字典的访问方法来处理这种类型的语法。
因此,必须在此处提出 TypeError: string indices must be integers, not str
例外。
<强> Q.E.D。强>
>>> import json
>>> print json.__doc__
JSON (JavaScript Object Notation) <http://json.org> is a subset of
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
interchange format.
[json] exposes an API familiar to users of the standard library
[marshal] and [pickle] modules. It is the externally maintained
version of the [json] library contained in Python 2.6, but maintains
compatibility with Python 2.4 and Python 2.5 and (currently) has
significant performance advantages, even without using the optional C
extension for speedups.
Encoding basic Python object hierarchies::
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print json.dumps("\"foo\bar")
"\"foo\bar"
>>> print json.dumps(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
Compact encoding::
>>> import json
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':'))
'[1,2,3,{"4":5,"6":7}]'
Pretty printing::
>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True,
... indent=4, separators=(',', ': '))
{
"4": 5,
"6": 7
}
Decoding JSON::
>>> import json
>>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
True
>>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
True
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)[0] == 'streaming API'
True
Specializing JSON object decoding::
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> from decimal import Decimal
>>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
True
Specializing JSON object encoding::
>>> import json
>>> def encode_complex(obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... raise TypeError(repr(o) + " is not JSON serializable")
...
>>> json.dumps(2 + 1j, default=encode_complex)
'[2.0, 1.0]'
>>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
'[2.0, 1.0]'
>>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
'[2.0, 1.0]'