Вчера вечером возникла страшная мысль. А можно ли связать OpenSSL и WSAEventSelect/WSAAssyncSelect?
Я пока не читал документацию на OpenSSL по этому поводу. Возможно стоит еще посмотреть, как включить SSL штатными средствами Windows.
Почему я стараюсь не использовать тысячу сторонних компонентов? И почему использую OpenSSL?
В своих программах я стараюсь использовать WinAPI, если сторонние библиотеки не дают никакого преимущества в простоте и скорости. Это обеспечивает простоту программы, надежность, наглядность, проблемы с совместимостью, отсутствие чужих ошибок и скорость. Посмотрите на прошлую программу, там нет ни одного выделения памяти. Все выделено уже на старте программы.
OpenSSL как раз отвечает таким требованиям.Для использования OpenSSL необходимо заменить функции send и recv на SSL_read, SSL_write. Ну куда проще? Просто сказка. А уже эти функции самые вызовут send и recv столько раз, сколько будет необходимо.
Для работы с сокетами я написал класс обертку, которая вызывает либо стандартную функцию recv, либо функцию SSL_read. Что конкретно вызовется, зависит от подключенного плагина.
Помимо этого, класс обертка благодаря дестрактору автоматически закрывает сокет. И позволяет не влезая в программу подключать различные библиотеки SSL и упрощает перенос программы.
Для фанатов ООП сразу скажу, что первая моя мысль была сделать интерфейс (абстрактный класс) Socket, и сделать реализации для обычных сокетов и SSL. Но подобная организация потребовала бы выделения памяти. А лишнее выделение памяти - лишние тормоза. Здесь же класс Socket создается на стеке и при использовании SSL никаких выделений памяти (со стороны программы) не требуется.
Плагин в случае OpenSSL выглядит так.
Проще и понятнее не придумаешь.
Быть или не быть...
Если не получится заставить работать асинхронные сокеты с OpenSSL, я буду использовать многопоточность. И сразу получаем кроссплатформенность, так как сокеты в Unix и Windows на этом уровне идентичны.
Есть еще неплохой вариант использовать штатные средства Windows. Он я ни разу с ними не работал.
Вот так вот. Думаешь пару дней про WSA, пишешь статью и оказывается, что будешь работать по старинке.
Я пока не читал документацию на OpenSSL по этому поводу. Возможно стоит еще посмотреть, как включить SSL штатными средствами Windows.
Почему я стараюсь не использовать тысячу сторонних компонентов? И почему использую OpenSSL?
В своих программах я стараюсь использовать WinAPI, если сторонние библиотеки не дают никакого преимущества в простоте и скорости. Это обеспечивает простоту программы, надежность, наглядность, проблемы с совместимостью, отсутствие чужих ошибок и скорость. Посмотрите на прошлую программу, там нет ни одного выделения памяти. Все выделено уже на старте программы.
OpenSSL как раз отвечает таким требованиям.Для использования OpenSSL необходимо заменить функции send и recv на SSL_read, SSL_write. Ну куда проще? Просто сказка. А уже эти функции самые вызовут send и recv столько раз, сколько будет необходимо.
Для работы с сокетами я написал класс обертку, которая вызывает либо стандартную функцию recv, либо функцию SSL_read. Что конкретно вызовется, зависит от подключенного плагина.
Помимо этого, класс обертка благодаря дестрактору автоматически закрывает сокет. И позволяет не влезая в программу подключать различные библиотеки SSL и упрощает перенос программы.
class Socket { public: SOCKET handle; void* sslData; SocketExtension* ssl; int recv(void* buf, int len); ... }; int Socket::recv(void* buf, int len) { return ext->recv(this, buf, len); // ext - указатель на класс DefaultSocketExtension или OpenSSL } // По умолчанию при вызове Socket::recv вызывается эта функция. DefaultSocketExtension существует // в одном экземпляре и не имеет данных. void DefaultSocketExtension::recv(Socket* s, void* buf, int len) { return ::recv(s->handle, buf, len); }
Для фанатов ООП сразу скажу, что первая моя мысль была сделать интерфейс (абстрактный класс) Socket, и сделать реализации для обычных сокетов и SSL. Но подобная организация потребовала бы выделения памяти. А лишнее выделение памяти - лишние тормоза. Здесь же класс Socket создается на стеке и при использовании SSL никаких выделений памяти (со стороны программы) не требуется.
Плагин в случае OpenSSL выглядит так.
class OpenSSL : public SocketExtension { public: virtual int recv(Socket* s, void* buf, int len) { return libssl32.SSL_read(s->sslData, buf, len); } virtual int send(Socket* s, const void* buf, int len) { return libssl32.SSL_write(s->sslData, buf, len); } virtual void close(Socket* s) { libssl32.SSL_free(s->sslData); closesocket(s->handle); s->handle = 0; } }; // OpenSSL существует в одном экземпляре и не имеет данных. static OpenSSL openSSL; SocketExtension* defaultSSL = openSSL;
Проще и понятнее не придумаешь.
Быть или не быть...
Если не получится заставить работать асинхронные сокеты с OpenSSL, я буду использовать многопоточность. И сразу получаем кроссплатформенность, так как сокеты в Unix и Windows на этом уровне идентичны.
Есть еще неплохой вариант использовать штатные средства Windows. Он я ни разу с ними не работал.
Вот так вот. Думаешь пару дней про WSA, пишешь статью и оказывается, что будешь работать по старинке.