Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
В чем смысл делать сокеты неблокирующими — а потом вызывать методы в цикле?
В реальных задачах используется хотя бы select
более продвинутых способовдля слушающего сокета?
проблеме c10kи является «неправильным способом», я правильно понимаю?
Сколько соединений сможет одновременно «держать» ваш сервер?
Хоть сколько.Неверно. Тот код, который я вижу, вообще не сможет обработать более одного соединения — это еще хуже, чем многопоточный сервер.
If the underlying BIO is non-blocking, SSL_do_handshake() will also return when the underlying BIO could not satisfy the needs of SSL_do_handshake() to continue the handshake. In this case a call to SSL_get_error() with the return value of SSL_do_handshake() will yield SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling process then must repeat the call after taking appropriate action to satisfy the needs of SSL_do_handshake(). The action depends on the underlying BIO. When using a non-blocking socket, nothing is to be done, but select() can be used to check for the required condition. When using a buffering BIO, like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue.www.openssl.org/docs/ssl/SSL_do_handshake.html
Вместо дескриптора сокета accept теперь вернет значение (-1).
accept возвращает -1 в никсах, а в винде она возращает INVALID_SOCKET
И немного не понял смысл замены блокирующего вызова на зацикленный неблокирующий.
Неблокирующий сокет нужен для обработки циклом клиентов и приёма новых конектов в одной ните, вместо разнесения этих операций по разным нитям.
Вы же сами ответили:
while(1) {
accept
...
// делаем что-то там нам нужное со старыми открытыми коннектами или с новым
}
...
// закрваем сокеты
typedef UINT_PTR SOCKET;
#define INVALID_SOCKET (SOCKET)(~0)
А что не так? Я в C/C++ новичок, но мне вот очевидно, что автор прав. В винде получится именно -1 при приведении к int именно из-за того, что в битовой форме все единицы.
Ну хотя бы то не так, что на винде дескриптор сокета - не число, а .указатель. И приведение его к int в лучшем случае просто не скомпилируется, а в худшем потеряет старшие биты (на 64х битных платформах) и не будет работать.
Не знаю как в винде, а в Visual Studio 2012 INVALID_SOCKET равен -1. Можете проверить, ссылка на готовый проект есть в статье.
Теоретически, вместо бесконечного цикла, можно с помощью функции select и ее более мощных аналогов, ждать пока сокет listen_sd станет доступен для чтения, а лишь потом один раз вызвать accept. Но лично я не вижу в моем способе с циклом никаких особых недостатков.
Кроссплатформенный https сервер с неблокирующими сокетами