Сокет Python отображается как доступный для записи даже после закрытия - PullRequest
0 голосов
/ 01 декабря 2018

Я видел несколько постов, в которых обсуждается проблема обнаружения закрытых сокетов.Большинство рекомендуют выбрать, что я сейчас и использую.Тем не менее, я вижу поведение, которое я не понимаю, и ищу совета.

У меня есть цикл обработки событий, работающий на сервере, который проверяет сообщения каждые 1/30 секунды (я использую неблокировка розеток).После получения сообщений сервер выполняет все необходимые задачи и добавляет исходящие сообщения в очередь отправки.В конце обновления я отправляю сообщения клиентам:

read, write, error = select.select([], self._CLIENTS.values(), [])

for sock in write:
    addr = sock.getpeername()
    if addr in self.__send_queue:
        for key in self.__send_queue[addr]:
            for msg in reversed(self.__send_queue[addr][key]):
                self._send(self._CLIENTS[addr], msg.encode())
                self._rmv_msg_from_queue(self.__send_queue, addr, key)

, где _CLIENTS содержит пару addr:sock, key - заголовок сообщения, указывающий, к чему относится сообщение,и __send_queue хранит список всех исходящих сообщений и заполняется после прочтения входящих сообщений.

Моя проблема может возникнуть из-за неправильного понимания того, как работает select, но я предположил, что если клиент отключился от сервера, когдаиспользуя select, клиент не будет отображаться в write.Моя проблема заключается в том, что когда я отключаю тестового клиента от сервера (через shutdown(1) и close()) и распечатываю write, он все равно показывает клиент как подключенный.

[] [<socket.socket fd=7, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 5000), raddr=('127.0.0.1', 46486)>]

Если я пытаюсь иотправить что-то, что я не вижу, чтобы получить какую-либо ошибку, но при последующей итерации события с сервера, write изменяется (больше не показывает соединение клиента)

[] [<socket.socket fd=7, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 5000)>]

и мои ошибки кода на addr = sock.getpeername() поскольку сокет не имеет аналогов.Я бы подумал, что write был бы пустым списком, так как сокет не доступен для записи, поэтому я никогда не должен входить в цикл.Почему select возвращает непустой write?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...