2013-11-26 76 views
3

我想翻译下面的示例HTTP服务器基于0MQ写在C看到这里:Hintjens' blog到Python。发送NULL消息在PyZMQ

def test_http_socket(): 
    ctx = zmq.Context() 
    sock = ctx.socket(zmq.ROUTER) 
    sock.setsockopt(zmq.ROUTER_RAW, 1) 
    sock.bind("tcp://*:8080") 
    while True: 
     id_bytes = sock.recv() 
     print("id=",id_bytes) 
     request = sock.recv() 
     print("request=",request) 
     if b'/close' in request: 
      return 
     sock.send(id_bytes, zmq.SNDMORE) 
     sock.send(b"""HTTP/1.0 200 OK 
Content-Type: text/plain 

Hello, world !""") 
     sock.send(zmq.NULL) 

的问题是在下一行,在那里我试着翻译了C表达式

zmq_send (router, NULL, 0, 0); 

在Python,我有以下堆栈跟踪:

Traceback (most recent call last): 
    File "<pyshell#96>", line 1, in <module> 
    test_http_socket() 
    File "<pyshell#95>", line 18, in test_http_socket 
    sock.send(zmq.NULL) 
    File "socket.pyx", line 565, in zmq.backend.cython.socket.Socket.send  (zmq\backend\cython\socket.c:5104) 
    File "socket.pyx", line 612, in zmq.backend.cython.socket.Socket.send (zmq\backend\cython\socket.c:4868) 
    File "socket.pyx", line 168, in zmq.backend.cython.socket._send_copy (zmq\backend\cython\socket.c:1914) 
    File "buffers.pxd", line 200, in buffers.asbuffer_r (zmq\backend\cython\socket.c:6833) 
    File "buffers.pxd", line 151, in buffers.asbuffer (zmq\backend\cython\socket.c:6270) 
TypeError: 0 does not provide a buffer interface. 

事实上,袜子.send只能用于发送缓冲区或消息。 有没有办法使用Python的另一种方式使用0MQ的zmq_send来发送NULL帧?

顺便说一句,在Github entry中的注释表明它可能不会关闭与客户端的连接,即使在C中。 如何让远程客户端关闭其连接(使用Python)?

我在Windows 32位上通过Python 3.3.2使用libzmq 4.0.1和PyZMQ 14.0.1。

回答

3

第一点:zmq.NULLZMQ_NULL常数,用于zeromq的安全机制。例如:

socket.mechanism = zmq.NULL # or zmq.PLAIN or zmq.CURVE 

它不是NULL特殊的C常数。

要发送空消息,简单地发送一个空的字节串:

socket.send(b'') 

第二点是,你需要发送空帧作为一个单独的消息,该消息你没有做。 这里是一个工作示例:

def http_hello_world(): 
    ctx = zmq.Context() 
    sock = ctx.socket(zmq.ROUTER) 
    sock.router_raw = True 
    sock.bind("tcp://*:8080") 
    while True: 
     id_bytes, request = sock.recv_multipart() 
     print("id: %r" % id_bytes) 
     print("request:", request.decode('utf8')) 
     if b'/close' in request: 
      return 

     # send the body of the response 
     sock.send_multipart([ 
      id_bytes, 
b"""HTTP/1.0 200 OK 
Content-Type: text/plain 

Hello, world! 
""" 
     ]) 
     # send an empty message to finish the response 
     sock.send_multipart([ 
      id_bytes, 
      b'' 
     ]) 

顺便说一句,在Github上条目的注释表明,我怎么能要求远程客户端关闭其可能不关闭,甚至C中的客户端的连接连接(在Python中)?

我想,只要你发送空帧来终止消息,连接应该被关闭。

+0

今天早上我想了一下,在重发一个空帧之前尝试发送id_bytes。为了以防万一,我回到了Stackoverflow,并且您提供了我在想的东西。它非常完美!谢谢。并感谢您对zmq.NULL的解释。 – Arglanir