New network subsystem: implemented the handshake...
...and started implementing reading/writing WML.
This commit is contained in:
parent
31ad9b2d06
commit
47d6e3b0a5
6 changed files with 137 additions and 6 deletions
|
@ -1130,6 +1130,12 @@ namespace {
|
|||
bool result = network_connect.show(disp.video());
|
||||
if(!result)
|
||||
return;
|
||||
config cfg, response;
|
||||
cfg.add_child("request_campaign_list");
|
||||
connection.transfer(cfg, response);
|
||||
result = network_connect.show(disp.video());
|
||||
if(!result)
|
||||
return;
|
||||
}
|
||||
const network::manager net_manager;
|
||||
const network::connection sock =
|
||||
|
|
|
@ -33,7 +33,7 @@ REGISTER_DIALOG(network_transmission)
|
|||
void tnetwork_transmission::pump_monitor::process(events::pump_info&)
|
||||
{
|
||||
connection_.poll();
|
||||
if(connection_.connected() && window_) {
|
||||
if(connection_.done() && window_) {
|
||||
window_.get().set_retval(twindow::OK);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#include "network_asio.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <iostream>
|
||||
#include "network_asio.hpp"
|
||||
#include "serialization/parser.hpp"
|
||||
|
||||
namespace network_asio {
|
||||
|
||||
connection::connection(const std::string& host, const std::string& service) :
|
||||
resolver_(io_service_), socket_(io_service_), connected_(false)
|
||||
resolver_(io_service_), socket_(io_service_), done_(false)
|
||||
{
|
||||
resolver_.async_resolve(
|
||||
boost::asio::ip::tcp::resolver::query(host, service),
|
||||
|
@ -45,8 +47,93 @@ void connection::handle_connect(
|
|||
connect(iterator);
|
||||
} else {
|
||||
std::cout << "Connected!\n";
|
||||
connected_ = true;
|
||||
handshake();
|
||||
}
|
||||
}
|
||||
|
||||
void connection::handshake()
|
||||
{
|
||||
static const boost::uint32_t handshake = 0;
|
||||
boost::asio::async_write(socket_,
|
||||
boost::asio::buffer(reinterpret_cast<const char*>(&handshake), 4),
|
||||
boost::bind(&connection::handle_write, this, _1, _2)
|
||||
);
|
||||
boost::asio::async_read(socket_,
|
||||
boost::asio::buffer(&handshake_response_.binary, 4),
|
||||
boost::bind(&connection::handle_handshake, this, _1)
|
||||
);
|
||||
}
|
||||
|
||||
void connection::handle_handshake(
|
||||
const boost::system::error_code& ec
|
||||
)
|
||||
{
|
||||
if(ec)
|
||||
throw error(ec);
|
||||
done_ = true;
|
||||
}
|
||||
|
||||
void connection::transfer(const config& request, config& /*response*/)
|
||||
{
|
||||
io_service_.reset();
|
||||
done_ = false;
|
||||
|
||||
std::ostream os(&write_buf_);
|
||||
write_gz(os, request);
|
||||
std::size_t size = write_buf_.size();
|
||||
size = htonl(size);
|
||||
boost::asio::write(socket_, boost::asio::buffer(reinterpret_cast<const char*>(&size), 4));
|
||||
boost::asio::async_write(socket_, write_buf_, boost::bind(&connection::handle_write, this, _1, _2));
|
||||
boost::asio::async_read(socket_, read_buf_,
|
||||
boost::bind(&connection::is_read_complete, this, _1, _2),
|
||||
boost::bind(&connection::handle_read, this, _1, _2));
|
||||
}
|
||||
|
||||
void connection::handle_write(
|
||||
const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred
|
||||
)
|
||||
{
|
||||
std::cout << "Written " << bytes_transferred << " bytes.\n";
|
||||
if(ec)
|
||||
throw error(ec);
|
||||
}
|
||||
|
||||
std::size_t connection::is_read_complete(
|
||||
const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred
|
||||
)
|
||||
{
|
||||
if(ec)
|
||||
throw error(ec);
|
||||
std::cout << "Read: " << bytes_transferred << '\n';
|
||||
if(bytes_transferred < 4) {
|
||||
return 4;
|
||||
} else {
|
||||
if(!bytes_to_read_) {
|
||||
std::istream is(&read_buf_);
|
||||
union { char binary[4]; boost::uint32_t num; } data_size;
|
||||
is.read(data_size.binary, 4);
|
||||
bytes_to_read_ = ntohl(data_size.num) + 4;
|
||||
}
|
||||
return bytes_to_read_.get() - bytes_transferred;
|
||||
}
|
||||
}
|
||||
|
||||
void connection::handle_read(
|
||||
const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred
|
||||
)
|
||||
{
|
||||
std::cout << "Read " << bytes_transferred << " bytes.\n";
|
||||
bytes_to_read_.reset();
|
||||
done_ = true;
|
||||
if(ec && ec != boost::asio::error::eof)
|
||||
throw error(ec);
|
||||
std::istream is(&read_buf_);
|
||||
config cfg;
|
||||
read_gz(cfg, is);
|
||||
std::cout << cfg;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#define NETWORK_ASIO_HPP_INCLUDED
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include "exceptions.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
namespace network_asio {
|
||||
|
||||
|
@ -21,7 +23,10 @@ class connection
|
|||
typedef boost::asio::ip::tcp::socket socket;
|
||||
socket socket_;
|
||||
|
||||
bool connected_;
|
||||
bool done_;
|
||||
|
||||
boost::asio::streambuf write_buf_;
|
||||
boost::asio::streambuf read_buf_;
|
||||
|
||||
void handle_resolve(
|
||||
const boost::system::error_code& ec,
|
||||
|
@ -33,7 +38,28 @@ class connection
|
|||
const boost::system::error_code& ec,
|
||||
resolver::iterator iterator
|
||||
);
|
||||
void handshake();
|
||||
void handle_handshake(
|
||||
const boost::system::error_code& ec
|
||||
);
|
||||
union {
|
||||
char binary[4];
|
||||
boost::uint32_t num;
|
||||
} handshake_response_;
|
||||
|
||||
void handle_write(
|
||||
const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred
|
||||
);
|
||||
std::size_t is_read_complete(
|
||||
const boost::system::error_code& error,
|
||||
std::size_t bytes_transferred
|
||||
);
|
||||
void handle_read(
|
||||
const boost::system::error_code& ec,
|
||||
std::size_t bytes_transferred
|
||||
);
|
||||
boost::optional<std::size_t> bytes_to_read_;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -44,6 +70,8 @@ class connection
|
|||
*/
|
||||
connection(const std::string& host, const std::string& service);
|
||||
|
||||
void transfer(const config& request, config& response);
|
||||
|
||||
/** Handle all pending asynchonous events and return */
|
||||
std::size_t poll()
|
||||
{
|
||||
|
@ -60,7 +88,8 @@ class connection
|
|||
*/
|
||||
void run() { io_service_.run(); }
|
||||
|
||||
bool connected() const { return connected_; }
|
||||
/** True if connected and no high-level operation is in progress */
|
||||
bool done() const { return done_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -484,3 +484,11 @@ void write(std::ostream &out, config const &cfg, unsigned int level)
|
|||
write_internal(cfg, out, textdomain, level);
|
||||
}
|
||||
|
||||
void write_gz(std::ostream &out, config const &cfg, unsigned int level)
|
||||
{
|
||||
boost::iostreams::filtering_stream<boost::iostreams::output> filter;
|
||||
filter.push(boost::iostreams::gzip_compressor());
|
||||
filter.push(out);
|
||||
|
||||
write(filter, cfg, level);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ void read(config &cfg, std::string &in); // Throws config::error
|
|||
void read_gz(config &cfg, std::istream &in);
|
||||
|
||||
void write(std::ostream &out, config const &cfg, unsigned int level=0);
|
||||
void write_gz(std::ostream &out, config const &cfg, unsigned int level=0);
|
||||
void write_key_val(std::ostream &out, const std::string &key, const config::attribute_value &value, unsigned level, std::string &textdomain);
|
||||
void write_open_child(std::ostream &out, const std::string &child, unsigned int level);
|
||||
void write_close_child(std::ostream &out, const std::string &child, unsigned int level);
|
||||
|
|
Loading…
Add table
Reference in a new issue