mogmail - boost::asio を利用したコネクタ
・connector.h
1: // Copyright (c) 2011 Mog Project. All rights reserved.
   2:  3: #ifndef _MOG_NET_CONNECTER_H_
4: #define _MOG_NET_CONNECTER_H_
5: #pragma once
   6:  7: #include <string>
8: #include <deque>
9: #include <boost/scoped_ptr.hpp>
10: #ifdef _WIN32
11: #define _WIN32_WINNT 0x0501
12: #endif // _WIN32
13: #include <boost/asio.hpp>
  14:  15: namespace mog {
16: namespace net {
  17:  18: // A class manages text-based TCP connection.
19: class Connecter {
20: public:
21: // Create connection to server.
22: Connecter(std::string const& address, std::string const& port, bool spool = false);
23: // Disconnect from server.
  24:   ~Connecter();25: // Write one line.
26: void WriteLine(std::string const& line);
27: // Read one line.
28: void ReadLine(std::string * line);
29: // Flush buffered messages.
30: void Flush();
31: // If there is no response, return true.
32: bool IsEmpty() const;
33: // Mutator of spool switch.
34: void set_spool(bool spool) { spool_ = spool; }
35: // Accessor of spool switch.
36: bool spool() const { return spool_; }
  37:  38: private:
39: static size_t const SOCKET_SIZE = 8192;
  40:   boost::asio::io_service                         io_service_;  41:   boost::scoped_ptr<boost::asio::ip::tcp::socket> socket_;  42:   std::deque<std::string>                         buffer_;43: bool spool_;
  44:  45: // Send requests.
46: void Request(std::string const& request);
47: // Recieve response.
48: void Response();
  49: };  50:  51: } // namespace net
52: } // namespace mog
53: #endif // _MOG_NET_CONNECTER_H_
1: // Copyright (c) 2011 Mog Project. All rights reserved.
   2:  3: #include "connecter.h"
4: #include <iostream>
5: #include <algorithm>
   6:  7: namespace mog {
8: namespace net {
   9:  10: ////////////////////////////////////////////////////////////////////////////////
11: // Connecter
12: Connecter::Connecter(std::string const& address, std::string const& port, bool spool)
13: : spool_(spool), socket_(new boost::asio::ip::tcp::socket(io_service_)) {
  14:   boost::asio::ip::tcp::resolver resolver(io_service_);  15:   boost::asio::ip::tcp::resolver::query query(address, port);  16:   boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);  17:   boost::asio::ip::tcp::resolver::iterator end;  18:    19:   boost::system::error_code error = boost::asio::error::host_not_found;  20:  21: while (error && endpoint_iterator != end) {
  22:     socket_->close();  23:     socket_->connect(*endpoint_iterator++, error);  24:   }25: if (error) {
26: throw boost::system::system_error(error);
  27:   }  28: }  29:    30: Connecter::~Connecter() {31: try {
  32:     socket_->close();33: } catch(...) {}
  34: }  35:  36: void Connecter::WriteLine(std::string const& line) {
37: Request(line + '\n');
  38: }  39:  40: void Connecter::ReadLine(std::string * line) {
41: if ( buffer_.empty() ) { Response(); }
  42:   *line = buffer_.front();  43:   buffer_.pop_front();  44: }  45:  46: void Connecter::Request(std::string const& request) {
  47:   socket_->write_some(boost::asio::buffer(request, request.size()));48: if (spool_) { std::cerr << "[SEND] " << request; }
  49: }  50:  51: void Connecter::Response() {
52: boost::array<char, SOCKET_SIZE> buf;
  53:   std::stringstream str;  54:  55: // Recieve socket.
56: for (;;) {
  57:     size_t length = socket_->read_some(boost::asio::buffer(buf));  58:     str.write(buf.data(), length);59: if (SOCKET_SIZE != length) { break; }
  60:   }  61:  62: // Convert lines to buffer.
  63:   std::string line;64: while (std::getline(str, line, '\n')) {
65: line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); // Remove carriage return.
  66:     buffer_.push_back(line);67: if (spool_) { std::cerr << "[RECV] " << line << '\n'; }
  68:   }  69: }  70:  71: void Connecter::Flush() {
72: if (socket_->available()) { // Thrown on faulure, boost::system::system_error.
  73:     Response();  74:   }  75:   buffer_.clear();  76: }  77:  78: bool Connecter::IsEmpty() const {
79: if (buffer_.empty() && !socket_->available()) { return true; }
80: return false;
  81: }  82:  83: } // namespace net
84: } // namespace mog
http://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E6%B6%88%E5%8E%BB%E3%83%BB%E5%89%8A%E9%99%A4(Erase-Remove)
0 件のコメント:
コメントを投稿