Почему `select ()` возвращает клиента как доступного для записи, когда клиент отключился? - PullRequest
0 голосов
/ 30 сентября 2018

Я реализую пример для использования select в простом эхо-сервере.Все работает нормально, клиент отправляет сообщение, получает эхо и отключается.

Это код, который я использовал для клиента:

import socket

ECHOER_PORT = 10000

if __name__ == '__main__':
    sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sockfd.connect(('localhost', ECHOER_PORT))

    msg = input('Message: ').encode()

    sockfd.send(msg)
    response = sockfd.recv(len(msg))
    print('Response: {}'.format(response))
    sockfd.close()

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

Я понимаю, почему он возвращается как читаемый, так как согласно статье:

Читаемый сокет без доступных данных получен от отключенного клиента, и поток готов к закрытию.

Но мой вопрос: почему также возвращается как доступный для записи?

1 Ответ

0 голосов
/ 30 сентября 2018

Но мой вопрос: почему также возвращается как доступный для записи?

Главное, что вы хотите сделать select(), когда клиент отключился, - это немедленный возврат, так что ваш кодможет обнаружить событие отключения и обработать его КАК МОЖНО СКОРЕЕ (закрыв сокет).

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

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

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