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;
}