使用select()的Python TCP Server [英] Python TCP Server using select()

查看:214
本文介绍了使用select()的Python TCP Server的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的第一个条目@stackoverflow;-))

this is my first entry @stackoverflow;-))

我需要一个Python3 TCP服务器,该服务器将客户端的所有输入发送给其他参与者.服务器可以工作,但是不幸的是,消息仅返回给发送客户端.第二个客户端发送内容后,它将立即获得所有条目.因此,这些条目在输出队列中可用.

I need a Python3 TCP server, which sends all inputs of the clients to the other participants. The server works, but unfortunately the message is only returned to the sending client. As soon as the second client sends something, it gets all entries.The entries are therefore available in the output queue.

为什么select()无法识别条目?

Why are the entries not recognized by select ()?

谢谢.

`

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]

`

推荐答案

您的问题是,仅当您从output列表中读取内容时,才将其添加到对等体中.相反,当您在其消息队列中写入内容时,应该这样做.

Your problem is that you only add a peer to the output list when you read something from it. You should instead do it when you write somthing to its message queue.

接收部分应变为:

        ...
        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:
            ...

根据您自己的要求,您只应为其他参与者排队留言:

According to your own requirements, you should only enqueue messages for other participants:

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

最后,您经常测试outputs中是否存在套接字.那让我们认为setlist更合适.

Finally, you often test existence of a socket in outputs. That let think that a set would be more appropriate than a list.

这篇关于使用select()的Python TCP Server的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆