Declarations
namespace ssl { typedef basic_sockmanager<SOCK_STREAM, AF_INET, 0> sockmanager; };
Overview
ssl::sockmanager は,SSL 通信用の sockmanager です. その他の sockmanager と同様のインターフェースで使用することができます.
Examples
#include <cstdio> #include <iostream> #include <string> #include "clx/ssl.h" /* ------------------------------------------------------------------------- */ // send_msg /* ------------------------------------------------------------------------- */ bool send_msg(clx::ssl::rawsocket* s, clx::ssl::sockmanager& sm) { // read string from std::cin std::string buf; if (!std::getline(std::cin, buf)) { sm.stop(); return false; } // write string to the socket for (clx::ssl::sockmanager::iterator pos = sm.begin(); pos != sm.end(); pos++) { if (sm.socket(pos)->socket() == s->socket()) continue; clx::ssl::sockstream* ss = dynamic_cast<clx::ssl::sockstream*>(sm.socket(pos)); *ss << buf << std::endl; } return true; } /* ------------------------------------------------------------------------- */ // recv_msg /* ------------------------------------------------------------------------- */ bool recv_msg(clx::ssl::rawsocket* s, clx::ssl::sockmanager& sm) { clx::ssl::sockstream* ss = dynamic_cast<clx::ssl::sockstream*>(s); std::string buf; if (!std::getline(*ss, buf)) { ss->close(); return false; } std::cout << buf << std::endl; return true; } /* ------------------------------------------------------------------------- */ // main /* ------------------------------------------------------------------------- */ int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "usage: " << argv[0] << " host" << std::endl; return -1; } try { clx::ssl::sockmanager sm; int port = clx::ssl::port(argv[2]); sm.add(new clx::ssl::sockstream(argv[1], port), recv_msg); sm.add(new clx::ssl::rawsocket(0), send_msg); // for std::cin sm.start(); } catch (clx::socket_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } catch (clx::sockaddress_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } catch (std::runtime_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } return 0; }
#include <iostream> #include <cstring> #include "clx/ssl.h" /* ----------------------------------------------------------------- */ // accept_handler /* ----------------------------------------------------------------- */ template <class Socket, class Service> class accept_handler { public: typedef Socket socket_type; typedef clx::ssl::acceptor acceptor_type; typedef Service service_handler; explicit accept_handler(const std::string& pub, const std::string& priv) : public_(pub), private_(priv) {} explicit accept_handler(const char* pub, const char* priv) : public_(pub), private_(priv) {} virtual ~accept_handler() throw() {} template <class T, class SockManager> bool operator()(T* s, SockManager& sm) { acceptor_type* server = dynamic_cast<acceptor_type*>(s); socket_type* client = new socket_type(server->accept(public_, private_)); if (client == NULL) throw std::bad_alloc(); sm.add(client, service_handler(server->socket())); return true; } private: std::string public_; std::string private_; }; /* ------------------------------------------------------------------------- */ // chat_service /* ------------------------------------------------------------------------- */ class chat_service { public: typedef clx::ssl::sockstream socket_type; chat_service(socket_int s) : accid_(s) {} template <class SockT, class SockManager> bool operator()(SockT* s, SockManager& sm) { socket_type* ss = dynamic_cast<socket_type*>(s); std::string ipaddr = ss->address().ipaddr(); int port = ss->address().port(); std::string buf; if (!std::getline(*ss, buf)) { std::cout << ipaddr << ':' << port << ": connection was closed" << std::endl; ss->close(); return false; } /* * 接続されている全クライアントに受信したメッセージを * message (xxx.xxx.xxx.xxx:port) * という形で送信する.ただし,sockmanager には接続確立用の * ソケットも登録されてあるため,そのソケットには送らないように * 注意する.コンストラクタで接続確立用のソケットのソケット番号 * を知らせてもらっている (accid_) ので,その値を基に判断する. */ buf += " (" + ipaddr + ":" + clx::lexical_cast<std::string>(port) + ")"; for (typename SockManager::iterator pos = sm.begin(); pos != sm.end(); pos++) { if (sm.socket(pos)->socket() == accid_) continue; socket_type* os = dynamic_cast<socket_type*>(sm.socket(pos)); *os << buf << std::endl; } return true; } private: socket_int accid_; // acceptorのソケット番号 }; /* ------------------------------------------------------------------------- */ // main /* ------------------------------------------------------------------------- */ int main(int argc, char* argv[]) { typedef accept_handler<clx::ssl::sockstream, chat_service> handler_type; try { clx::ssl::sockmanager s; int port = clx::ssl::port(argv[1]); s.add(new clx::ssl::acceptor(port), handler_type("public.key", "private.key")); s.start(); } catch (clx::socket_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } catch (clx::sockaddress_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } catch (std::runtime_error& e) { std::cerr << e.what() << std::endl; std::exit(-1); } return 0; }