Сокеты в Linux - как узнать, что клиент закончил? - PullRequest
0 голосов
/ 08 мая 2011

В настоящее время я пытаюсь реализовать свой собственный веб-сервер на C ++ - не для продуктивного использования, а для обучения.

Я в основном открываю сокет, слушаю, жду соединения и открываю новый сокет, из которого япрочитайте данные, отправленные клиентом.Все идет нормально.Но как я узнаю, что клиент закончил отправку данных, а не просто временно прекратил отправлять больше по какой-то другой причине?

Мой текущий пример: когда клиент отправляет POST-запрос, он сначала отправляет заголовки, затемдва раза "\ r \ n" подряд и затем тело запроса.Иногда тело не содержит никаких данных.Так что, если клиент временно не может отправить что-либо после отправки заголовков - как мне узнать, что он еще не завершил свой запрос?

Это зависит исключительно от используемого протокола (HTTP), и это мойзадача выяснить это на основе данных, которые я получил, или есть что-то вроде EOF для сокетов?

Если я не могу получить необходимую информацию из сокета, как я могу защитить свою программу от неисправных клиентов?(Что, я полагаю, я должен сделать независимо от этого, так как это может быть злоумышленник, а не неисправный клиент, отправляющий неверные данные.) Это мой единственный вариант - продолжать чтение до тех пор, пока запрос не будет завершен по определению протокола или по таймауту (определяетсяя) достигнут?

Надеюсь, это имеет смысл.

Кстати: пожалуйста, не говорите мне использовать какую-то библиотеку - я хочу изучить основы.

Ответы [ 3 ]

1 голос
/ 08 мая 2011

Протокол (HTTP) сообщает вам, когда клиент прекратил отправку данных.Вы не можете получить информацию из сокета, так как клиент оставит его открытым в ожидании ответа.

Как вы говорите, вы должны остерегаться ошибочных клиентов, не отправляющих надлежащие запросы.Обычно в случае неполного запроса тайм-аут применяется к чтению.Если вы ничего не получили в течение 30 секунд, скажем, затем закройте сокет и проигнорируйте его.

Для сообщения HTTP должен быть заголовок (Content-Length), указывающий, сколько байтов ожидать послеконец заголовков.Если это POST и нет Content-Length, отклоните его.

1 голос
/ 08 мая 2011

С текстовыми протоколами, такими как HTTP, вы зависите от клиента. Наиболее хорошо отформатированный POST будет иметь длину содержимого, чтобы вы знали, сколько данных поступает. Однако клиент может просто отложить отправку данных, либо ему может быть удален Ethernet-кабель, либо он просто зависает, и в этом случае этот сокет находится там бесконечно долго. Если он нормально отключится, вы получите событие / ответ о закрытии сокета от recv ().

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

1 голос
/ 08 мая 2011

«Это зависит исключительно от используемого протокола (HTTP), и моя задача - выяснить это на основе полученных данных»,

Правильно. Вы можете найти спецификации HTTP через Google; http://www.w3.org/Protocols/rfc2616/rfc2616.html

"или есть что-то вроде EOF для сокетов?"

Есть так, как он ведет себя так же, как файл ... но здесь это не применимо, потому что клиент не закрывает соединение; Вы отправляете ответ на это соединение.

...