2017-11-13 1 views
1

이 내 첫 번째 항목의 @stackoverflow ;-))파이썬 TCP 서버를 선택()

내가 다른 참가자들에게 모든 클라이언트 입력을 보내는 Python3 TCP 서버가 필요합니다. 서버가 작동하지만 불행히도 메시지는 보내는 클라이언트에만 반환됩니다. 두 번째 클라이언트가 뭔가를 보내 자마자 모든 항목을 가져옵니다. 따라서 항목을 출력 대기열에서 사용할 수 있습니다.

왜 항목이 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: 
      ... 

을 자신의 요구 사항에 따라, 당신은 다른 참가자 만 대기열에 메시지가 있어야합니다

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

마지막으로, 당신이 종종 outputs에 소켓의 존재를 테스트 . 그게 이 list보다 더 적절할 것이라고 생각합니다.

+0

그게 전부 야! 서지 감사합니다! – MartinH

+1

@MartinH : 천만에요. 도움이된다면 답을 받아 들여 (확인 표시) 미래의 독자들에게이 질문에 해결책이 있음을 알릴 수 있습니까? –

+0

잘 작동합니다. 많은 Thx @ Serge – MartinH

관련 문제