python select 使用

2022-05-13 10:05:40 浏览数 (1)

coding:utf-8

author = 'Alex Li'

import select import socket import sys import queue

Create a TCP/IP socket

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

Bind the socket to the port

server_address = ('localhost', 10000) print(sys.stderr, 'starting up on %s port %s' % server_address) server.bind(server_address)

Listen for incoming connections

server.listen(5)

Sockets from which we expect to read

inputs = [ server ]

Sockets to which we expect to write

outputs = [ ]

message_queues = {} while inputs:

代码语言:javascript复制
# Wait for at least one of the sockets to be ready for processing
print( 'nwaiting for the next event')
readable, writable, exceptional = select.select(inputs, outputs, inputs)
# Handle 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(False)
        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(sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) )
            message_queues[s].put(data)
            # Add output channel for response
            if s not in outputs:
                outputs.append(s)
        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)  #既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉
            inputs.remove(s)    #inputs中也删除掉
            s.close()           #把这个连接关闭掉

            # Remove message queue
            del message_queues[s]
# Handle outputs
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)
# Handle "exceptional conditions"
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]

import sys, time from select import select from socket import socket, AF_INET, SOCK_STREAM def now(): return time.ctime(time.time())

myHost = '' # server machine, '' means local host myPort = 50007 # listen on a non-reserved port number if len(sys.argv) == 3: # allow host/port as cmdline args too myHost, myPort = sys.argv[1:] numPortSocks = 2 # number of ports for client connects

make main sockets for accepting new client requests

mainsocks, readsocks, writesocks = [], [], [] for i in range(numPortSocks): portsock = socket(AF_INET, SOCK_STREAM) # make a TCP/IP socket object portsock.bind((myHost, myPort)) # bind it to server port number portsock.listen(5) # listen, allow 5 pending connects mainsocks.append(portsock) # add to main list to identify readsocks.append(portsock) # add to select inputs list myPort = 1 # bind on consecutive ports

event loop: listen and multiplex until server process killed

print('select-server loop starting') while True: #print(readsocks) readables, writeables, exceptions = select(readsocks, writesocks, []) for sockobj in readables: if sockobj in mainsocks: # for ready input sockets # port socket: accept new client newsock, address = sockobj.accept() # accept should not block print('Connect:', address, id(newsock)) # newsock is a new socket readsocks.append(newsock) # add to select list, wait else: # client socket: read next line data = sockobj.recv(1024) # recv should not block print('tgot', data, 'on', id(sockobj)) if not data: # if closed by the clients sockobj.close() # close here and remv from readsocks.remove(sockobj) # del list else reselected else: # this may block: should really select for writes too reply = 'Echo=>%s at %s' % (data, now()) sockobj.send(reply.encode())

0 人点赞