2016-07-21 3 views
0

У меня есть статический DNS с именем vops-server.com, который указывает на мой Dell PowerEdge 2950. На этом 2950 я бегу server.py который первоначально связывается tcp://0.0.0.0:7777, а затем перенаправляет все входящие клиентов к гнездо привязано к порту, превышающему 7777, первым из которых является 7778. Эта вновь созданная пара ROUTER-DEALER просто эхо "Hello, world!".ZeroMQ роутер-ДИЛЕР перенаправлять на другой вопрос роутер-ДИЛЕРА

Dell PowerEdge 2950 работает Ubuntu 16.04.1 LTS и не запускать код должным образом, вывод следующий на платформе KeyboardInterrupt:

k▒Eg 
Listening on port 7778 
Recv 
Resource temporarily unavailable 
Client on port 7778 disconnected 
^CProcess Process-3: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap 
    self.run() 
    File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run 
    self._target(*self._args, **self._kwargs) 
    File "test_server.py", line 76, in worker_task 
    data = worker_socket.recv_multipart() 
    File "/usr/local/lib/python2.7/dist-packages/zmq/sugar/socket.py", line 395, in recv_multipart 
    parts = [self.recv(flags, copy=copy, track=track)] 
    File "zmq/backend/cython/socket.pyx", line 693, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:7283) 
    File "zmq/backend/cython/socket.pyx", line 727, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:7081) 
    File "zmq/backend/cython/socket.pyx", line 145, in zmq.backend.cython.socket._recv_copy (zmq/backend/cython/socket.c:2033) 
    File "zmq/backend/cython/checkrc.pxd", line 12, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:7522) 
    PyErr_CheckSignals() 
KeyboardInterrupt 

В то время как клиент выводит следующее:

Connecting to distribution server tcp://vops-server.com:7777 
[Dist] Send 
[Dist] Recv 
[Dist] 7778 
Connecting to host tcp://vops-server.com:7778 
[Host] Send 
[Host] Recv 

В этот момент клиент должен вывести окончательную строку [Host] Hello, world!, но она зависает в ожидании получения сообщения.

Теперь на моем ноутбуке, который работает Windows 10 Home 1511, выход, как ожидается:

Ç ) 
Listening on port 7778 
Recv 
['\x00\x80\x00\x00)', 'Hello, world!'] 
Sent 

С клиентом теперь правильно выводящим:

Connecting to distribution server tcp://vops-server.com:7777 
[Dist] Send 
[Dist] Recv 
[Dist] 7778 
Connecting to host tcp://vops-server.com:7778 
[Host] Send 
[Host] Recv 
[Host] Hello, world! 

Пожалуйста, ознакомьтесь с кодом ниже.

server.py:

import sys 
import zmq 
from multiprocessing import Process, Queue, Array, Value 
import time 

def server_task(): 
    port_base = 7777 

    server_context = zmq.Context.instance() 

    server_socket = server_context.socket(zmq.ROUTER) 

    server_socket.bind("tcp://0.0.0.0:%d" % (port_base,)) 

    timeout_queue = Queue() 
    port_list = [ 1 ] 

    proc_list = [ ] 

    while True: 
     try: 
      client_id = server_socket.recv_multipart()[0] 

      print(client_id) 

      # Get an unused port from the list 
      # Ports from clients that have timed out are recycled here 

      while not timeout_queue.empty(): 
       port_list.append(timeout_queue.get()) 

      port_offset = port_list.pop() 

      if len(port_list) == 0: 
       port_list.append(port_offset + 1) 

      # Spawn a new worker task, binding the port to a socket 

      proc_running = Value("b", True) 

      proc_list.append(proc_running) 

      Process(target=worker_task, args=(proc_running, port_base, port_offset, timeout_queue)).start() 

      # Send the new port to the client 

      server_socket.send_multipart([client_id, str(port_base + port_offset)]) 

     except KeyboardInterrupt: 
      break 

    for proc_running in proc_list: 
     proc_running.value = False 

    server_socket.close() 
    server_context.term() 

def worker_task(proc_running, port_base, port_offset, timeout_queue): 
    port = port_base + port_offset 

    print("Listening on port %d" % (port,)) 

    worker_context = zmq.Context.instance() 

    worker_socket = worker_context.socket(zmq.ROUTER) 

    worker_socket.setsockopt(zmq.RCVTIMEO, 5000) 
    worker_socket.bind("tcp://0.0.0.0:%d" % (port,)) 

    while proc_running.value: 
     try: 
      print("Recv") 
      data = worker_socket.recv_multipart() 

      print(data) 
      worker_socket.send_multipart(data) 

      print("Sent") 
     except zmq.ZMQError as e: 
      print(e) 
      break 

    print("Client on port %d disconnected" % (port,)) 

    timeout_queue.put(port_offset) 

    worker_socket.close() 
    worker_context.term() 

if __name__ == "__main__": 
    server_task() 

client.py:

import os 
import io 
import time 
import zmq 
from multiprocessing import Process 

def connect_to_host(context, host, port, timeout): 
    address = ("tcp://%s:%s" % (host, port)) 

    socket = context.socket(zmq.DEALER) 

    socket.setsockopt(zmq.RCVTIMEO, timeout) 
    socket.connect(address) 

    print("Connecting to distribution server %s" % (address,)) 

    while True: 
     try: 
      print("[Dist] Send") 
      socket.send_multipart([str(0)]) 
      print("[Dist] Recv") 
      port = socket.recv_multipart()[0] 
      print("[Dist] %s" % (port,)) 

      break 
     except zmq.Again: 
      socket.close() 

      socket = context.socket(zmq.DEALER) 

      socket.setsockopt(zmq.RCVTIMEO, timeout) 
      socket.connect(address) 

      print("Connecting to distribution server %s" % (address,)) 

    socket.close() 

    address = ("tcp://%s:%s" % (host, port)) 

    socket = context.socket(zmq.DEALER) 

    socket.setsockopt(zmq.RCVTIMEO, timeout) 
    socket.connect(address) 

    print("Connecting to host %s" % (address,)) 

    return socket 

def client_task(client_type): 
    timeout = 5000 
    host = "vops-server.com" 
    port = "7777" 

    context = zmq.Context().instance() 

    socket = connect_to_host(context, host, port, timeout) 

    while True: 
     try: 
      try: 
       print("[Host] Send") 
       socket.send_multipart(["Hello, world!"]) 

       print("[Host] Recv") 
       data = socket.recv_multipart()[0] 

       print("[Host] %s" % (data,)) 
      except zmq.Again: 
       socket.close() 

       socket = connect_to_host(context, host, port, timeout) 

     except KeyboardInterrupt: 
      break 

    print("Connection terminated") 

    socket.close() 
    context.term() 

if __name__ == "__main__": 
    client_task(0) 

Я не могу понять, почему тот же код работает на одной машине, а не другой; Я рассмотрел возможность установки Windows Server 2012 на Dell PowerEdge 2950 с надеждой, что ошибка лежит в ОС, а не на самом аппаратном обеспечении. Пока я жду и надеюсь, что у эксперта есть решение моей проблемы.

ответ

0

Тот же код отлично работает на Dell PowerEdge 2950 под управлением Windows Server 2012 R2. У ZMQ есть проблемы с Ubuntu.

Смежные вопросы