2017-11-13 11 views
1

これが私の最初のエントリ@stackoverflow ;-))PythonのTCPサーバーのselect()

私は他の参加者にクライアントのすべての入力を送るのpython3 TCPサーバーが、必要です。サーバーは機能しますが、残念ながらメッセージは送信側クライアントにのみ返されます。 2番目のクライアントが何かを送信するとすぐに、すべてのエントリが取得されます。したがって、エントリは出力キューで使用できます。

select()でエントリが認識されないのはなぜですか?

サポートのためのThx。

`

import select 
import socket 
import sys 
import queue 

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
server.setblocking(0) 

server_address = ('192.168.100.28', 8888) 
print ("starting up on %s port %s" % server_address) 
server.bind(server_address) 

server.listen(5) 

inputs = [ server ] 
outputs = [ ] 
message_queues = {} 




while inputs: 
    print ("\nwaiting for the next event") 
    readable, writable, exceptional = select.select(inputs, outputs, inputs) 

ハンドル入力

for s in readable: 

    if s is server: 
     # A "readable" server socket is ready to accept a connection 
     connection, client_address = s.accept() 
     print ("new connection from", client_address) 
     connection.setblocking(0) 
     inputs.append(connection) 

     # Give the connection a queue for data we want to send 
     message_queues[connection] = queue.Queue() 
    else: 
     data = s.recv(1024) 
     if data: 
      # A readable client socket has data 
      print ('received "%s" from %s' % (data, s.getpeername())) 
      # Add output channel for response 
      #message_queues[s].put(data) 
      if s not in outputs: 
       outputs.append(s) 
      for aQueue in message_queues: 
       message_queues[aQueue].put(data) 
       # AQueue.send ("Test".encode()) 
     else: 
      # Interpret empty result as closed connection 
      print ("closing", client_address, "after reading no data") 
      # Stop listening for input on the connection 
      if s in outputs: 
       outputs.remove(s) 
      inputs.remove(s) 
      s.close() 

      # Remove message queue 
      del message_queues[s] 

ハンドル出力

for s in writable: 
    try: 
     next_msg = message_queues[s].get_nowait() 
    except queue.Empty: 
     # No messages waiting so stop checking for writability. 
     print ("output queue for", s.getpeername(), "is empty") 
     outputs.remove(s) 
    else: 
     print ('sending "%s" to %s' % (next_msg, s.getpeername())) 
     s.send(next_msg) 

ハンドル "例外条件"

for s in exceptional: 
    print ("handling exceptional condition for", s.getpeername()) 
    # Stop listening for input on the connection 
    inputs.remove(s) 
    if s in outputs: 
     outputs.remove(s) 
    s.close() 

    # Remove message queue 
    del message_queues[s] 

`

答えて

1

あなたの問題は、あなたがそれから何かを読んだときだけoutputリストにピアを追加することです。代わりにメッセージキューに何かを書き込むときにそれを行うべきです。

受信部はなるはずです:

 ... 
     data = s.recv(1024) 
     if data: 
      # A readable client socket has data 
      print ('received "%s" from %s' % (data, s.getpeername())) 
      # Add output channel for response 
      #message_queues[s].put(data) 
      # if s not in outputs: 
      # outputs.append(s) 
      for aQueue in message_queues: 
       message_queues[aQueue].put(data) 
       if aQueue not in outputs:  # enqueue the msg 
        outputs.append(aQueue)  # and ask select to warn when it can be sent 
       # AQueue.send ("Test".encode()) 
     else: 
      ... 

は、独自の要件によると、あなたは他の参加者のためにだけメッセージをエンキューする必要があります。最後に、あなたは、多くの場合、outputsソケットの存在を

  for aQueue in message_queues: 
       if aQueue != s:  # only send to other participants 
        ... 

テスト。それで、setlistよりも適切であると考えてください。

+0

それはそれです! Sergeありがとう! – MartinH

+1

@MartinH:どうぞよろしくお願いいたします。それが助けられたら、答えを受け入れることができます(チェックマーク)。将来の読者にこの問題に解決策があることを教えてください。 –

+0

それはとてもうまく動作します。多くのThx @ Serge – MartinH

関連する問題