Python Socket WebChat, я не понимаю Select.select() и как он работает

Я не хочу делать этот пост длинным, поэтому я сразу перейду к той части, которую я не понимаю

это код, который я получил отсюда, я уже сделал свое собственное приложение, но я сделал его самым ужасным способом!

# 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()

Я не понимаю ту часть, которая использует select и добавляет новые соединения, я думаю, каждый раз, когда приложение пытается подключиться (myport, myip), создается новый дескриптор, и этот метод пытается получить людей, которые подключаются ()? можешь мне объяснить? и я понятия не имею, почему сокет сервера добавляется к сокету и почему его передают на выбор! Я уже читал это, но я все еще не понимаю

я тоже не понимаю почему if sock == server_socket: означает, что есть новое соединение, я думаю, что его, потому что я до сих пор не понял, выберите

1 ответ

Решение

Select() (как и функция select() в C) - это нечто волшебное. Это позволяет вам ждать события, не занимая процессор компьютера.

События, в вашем случае, являются операциями ввода и вывода сокета. Представьте, что вы ждете перед закрытыми дверями ("вы" - процессор). (Правильная) дверь откроется, если что-то полезное можно сделать. Каждая дверь ведет к операции ввода / вывода, которая добавляется в CONNECTION_LIST.

Во время ожидания процессор не тратит время на вашу программу. В зависимости от того, какая дверь откроется первой, процессор будет разбужен и позволит вам обрабатывать данные.

Примечание. В Linux метод select() работает со всеми файловыми операциями (например, в данном случае с сокетами). В Windows это работает только на сокетах.

Примечание 2: Хотя сокеты работают нормально, я предпочитаю механизм обратного вызова, такой как iowatch из библиотеки gio (часть glib). Они будут вызывать функции, когда необходима операция.

Другие вопросы по тегам