2016-12-11 64 views
0

我正在一个连续发送数据到客户端的服务器上工作。该客户端也可以与发送特定请求的服务器交互守时。我写了一个守护进程来做到这一点。请注意,这个守护进程在一个线程中工作。现在,脚本结构如下:Python,通过两个套接字进行通信

class MyDaemon(threading.Thread): 

    def __init__(self): 

     # Init Stream socket (output) 
     self.MainSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.MainSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.MainSock.bind(('', 15555)) 
     self.MainSock.listen(5) 
     self.MainSock.setblocking(0) 

     # Init Request socket (input) 
     self.RequestSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     self.RequestSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.RequestSock.bind(('', 15556)) 
     self.RequestSock.listen(5) 
     self.RequestSock.setblocking(0) 


    def run(self): 

     while True: 

      # Listen to connection on MainSock 
      try: 
       self.stream, address = self.MainSock.accept() 
      except: 
       pass 

      # Listen to connection on RequestSock 
      try: 
       self.request, address = self.RequestSock.accept() 
      except: 
       pass 

      if self.stream: 
       send_message_continuously() # it is a stream 

      if self.request: 
       recv_a_message_from_client() 
       do_whatever_action_the client_request() 

的问题是:

  • 只用蒸笼,一切工作正常。

  • 只使用请求者,一切正常。

  • 使用两个插座同时阻挡流光。

我看到一个线程无法同时连接(或连接)到两个套接字。我还读到,使用select模块可能有助于处理这种问题,但我从来没有使用过它,并且我对在特定情况下使用它有点失落。

什么是更有效的方式来处理这个问题? 如何在我的特殊情况下设置select? 将发送到子线程并将请求发送到另一个会更高效/简单吗?

编辑:最后,我用了一个子线程的

+0

FWIW,在Python线程是关于一种单纯的方便,而不是效率(有一些例外,如调用C明确释放GIL的模块)。 – spectras

回答

1

我建议你去尝试gevent,简单understant的API,它的好走,如果你想克服的问题,有一个关于servers 的部分了解tcp通信&重新考虑你当前的解决方案。
代码卡 -

def handle(socket, address): 
    print('new connection!') 

server = StreamServer(('127.0.0.1', 1234), handle) # creates a new server 
server.start() # start accepting new connections 

希望你能花更多的时间提出申请未做skelts。 :)

2

当使用select你必须测试,你的两个插座的准备接受:

def run(self): 
    while True: 
     ready, _, _ = select.select([self.MainSock, self.RequestSock],[],[]) 
     for sock in ready: 
      if sock is self.MainSock: 
       send_message_continuously(sock.accept()) 
      elif sock is self.RequestSock: 
       recv_a_message_from_client(sock.accept()) 
+0

客户端是否也必须使用'select'? –

+0

如果您想处理新的传入客户端,同时处理一个客户端,是的。但是,使用线程或一些asyncio库会更容易。 – Daniel

相关问题