简体   繁体   中英

Python Socket WebChat, I don't understand Select.select() and how it works

I don't want to make this post long so i get straight to the part i don't understand

this is the code i got from here i aleady made my own app, but i made it the most awful way!

# Tcp Chat server

import socket, select

#Function to broadcast chat messages to all connected clients
def broadcast_data (sock, message):
    #Do not send the message to master socket and the client who has send us the message
    for socket in CONNECTION_LIST:
        if socket != server_socket and socket != sock :
            try :
                socket.send(message)
            except :
                # broken socket connection may be, chat client pressed ctrl+c for example
                socket.close()
                CONNECTION_LIST.remove(socket)

if __name__ == "__main__":

    # List to keep track of socket descriptors
    CONNECTION_LIST = []
    RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
    PORT = 5000

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # this has no effect, why ?
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('', PORT))
    6.listen(10)

    # Add server socket to the list of readable connections
    CONNECTION_LIST.append(server_socket)

    print "Chat server started on port " + str(PORT)

    while 1:
        # Get the list sockets which are ready to be read through select
        read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])

        for sock in read_sockets:
            #New connection
            if sock == server_socket:
                # Handle the case in which there is a new connection recieved through server_socket
                sockfd, addr = server_socket.accept()
                CONNECTION_LIST.append(sockfd)
                print "Client (%s, %s) connected" % addr

                broadcast_data(sockfd, "[%s:%s] entered room\n" % addr)

            #Some incoming message from a client
            else:
                # Data recieved from client, process it
                try:
                    #In Windows, sometimes when a TCP program closes abruptly,
                    # a "Connection reset by peer" exception will be thrown
                    data = sock.recv(RECV_BUFFER)
                    if data:
                        broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '> ' + data)                

                except:
                    broadcast_data(sock, "Client (%s, %s) is offline" % addr)
                    print "Client (%s, %s) is offline" % addr
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                    continue

    server_socket.close()

i don't understand the part which uses select and adds a new connections, i guess every time an app tries to connect(myport,myip) a new descriptor is created and this method tries to get connect()ed people? can you explain me? and i have no idea why the server socket is appended to the socket and why its passed to select! I already read this but i still don't understand

i also don't understand why if sock == server_socket: means there is a new connection, i think its because i still haven't understood select

Select() (like the select() function in C) is somewhat magic. It enables you to wait for a events, without occupying the computer's CPU.

The events, in your case, are the input and output operations of the socket. Imagine you're waiting before closed doors ('you' are the CPU). The (correct) door will open if something useful can be done. Each door leads to the an I/O operation which is added to the CONNECTION_LIST.

While waiting, the CPU doesn't spend time on your program. Whichever door opens first, will wake the CPU, and lets you process the data.

Note: In Linux, select() works on all file operations (such as, in this case sockets). In Windows, this only works on sockets.

Note2: Though sockets work fine, I rather prefer a callback mechanism, such as iowatch from the gio library (part of glib). These will call functions when an operation is necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM