2013-11-26 122 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