блокировка розеток и выбор - PullRequest
1 голос
/ 23 февраля 2011

Я играю с сокетами, и у меня есть некоторые сомнения по поводу использования блокирующих сокетов с select. Предположим, я отслеживаю только потенциальных читателей.Правильно ли я думаю, что select будет проходить через первый сокет в списке, и если будут доступны некоторые данные, он вернется и, если нет, заблокирует его до истечения времени ожидания select?Когда другие сокеты в списке чтения будут проверены с помощью select?

Позвольте мне проиллюстрировать на примере Python для простоты:

servsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servsock.bind(("", 2500))
servsock.listen(15)
servsock.setblocking(1)

readlist = [servsock]

while 1:
    (sread, swrite, sexc) =  select.select(readlist, [], [] ); 

    for sock in sread:

        #received a connect to the server socket
        if  sock == servsock:

        (newsock, address) = servsock.accept()
            newsock.setblocking(1)
            print "I got a connection from ", address
            readlist.append(newsock)
            newsock.send("you're connected to the select server")
        else:
            recv_msg = sock.recv(5)

            if recv_msg == "":
                (host, port) = sock.getpeername()
                print "Client %s:%s closed the connection" % (host,port)
                sock.close()
                readlist.remove(sock)
            else:
                (host, port) = sock.getpeername()
                print "client %s:%s sent: %s "% (host,port,recv_msg)

Поскольку они блокируют сокеты, будет выбран всегда блокпри тестировании, чтобы увидеть, есть ли в сокете в списке данные для чтения?

Ответы [ 2 ]

5 голосов
/ 23 февраля 2011

API select() C возвращает список всех сокетов, которые в данный момент доступны для чтения.Предполагая, что оболочка Python делает то же самое, sread будет содержать несколько элементов, если несколько сокетов доступны для чтения.

Блокирующий сокет будет блокироваться только при отсутствии данных, поэтому после вызова select(), указанного, есть данные, вы можете предположить, что один вызов recv не будет блокироваться.

2 голосов
/ 23 февраля 2011

select() будет блокироваться, пока один из сокетов не получит данные. Он не проверяет только первый, он проверяет все в вашей переменной readlist.

В for sock in sread: он перебирает все сокеты, в которых есть данные для чтения.

...