mirror of
https://github.com/monero-project/monero.git
synced 2025-08-07 09:22:19 -04:00
moved all stuff to github
This commit is contained in:
parent
095fbeeb67
commit
296ae46ed8
388 changed files with 95937 additions and 469 deletions
683
contrib/epee/include/net/net_helper.h
Normal file
683
contrib/epee/include/net/net_helper.h
Normal file
|
@ -0,0 +1,683 @@
|
|||
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include <Winsock2.h>
|
||||
//#include <Ws2tcpip.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/preprocessor/selection/min.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
||||
#include "net/net_utils_base.h"
|
||||
#include "misc_language.h"
|
||||
//#include "profile_tools.h"
|
||||
#include "../string_tools.h"
|
||||
|
||||
#ifndef MAKE_IP
|
||||
#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
|
||||
#endif
|
||||
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
class blocked_mode_client
|
||||
{
|
||||
|
||||
|
||||
struct handler_obj
|
||||
{
|
||||
handler_obj(boost::system::error_code& error, size_t& bytes_transferred):ref_error(error), ref_bytes_transferred(bytes_transferred)
|
||||
{}
|
||||
handler_obj(const handler_obj& other_obj):ref_error(other_obj.ref_error), ref_bytes_transferred(other_obj.ref_bytes_transferred)
|
||||
{}
|
||||
|
||||
boost::system::error_code& ref_error;
|
||||
size_t& ref_bytes_transferred;
|
||||
|
||||
void operator()(const boost::system::error_code& error, // Result of operation.
|
||||
std::size_t bytes_transferred // Number of bytes read.
|
||||
)
|
||||
{
|
||||
ref_error = error;
|
||||
ref_bytes_transferred = bytes_transferred;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
inline
|
||||
blocked_mode_client():m_socket(m_io_service),
|
||||
m_initialized(false),
|
||||
m_connected(false),
|
||||
m_deadline(m_io_service),
|
||||
m_shutdowned(0)
|
||||
{
|
||||
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
|
||||
// No deadline is required until the first socket operation is started. We
|
||||
// set the deadline to positive infinity so that the actor takes no action
|
||||
// until a specific deadline is set.
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
|
||||
// Start the persistent actor that checks for deadline expiry.
|
||||
check_deadline();
|
||||
|
||||
}
|
||||
inline
|
||||
~blocked_mode_client()
|
||||
{
|
||||
//profile_tools::local_coast lc("~blocked_mode_client()", 3);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
inline void set_recv_timeout(int reciev_timeout)
|
||||
{
|
||||
m_reciev_timeout = reciev_timeout;
|
||||
}
|
||||
|
||||
inline
|
||||
bool connect(const std::string& addr, int port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
|
||||
{
|
||||
return connect(addr, std::to_string(port), connect_timeout, reciev_timeout, bind_ip);
|
||||
}
|
||||
|
||||
inline
|
||||
bool connect(const std::string& addr, const std::string& port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
|
||||
{
|
||||
m_connect_timeout = connect_timeout;
|
||||
m_reciev_timeout = reciev_timeout;
|
||||
m_connected = false;
|
||||
if(!m_reciev_timeout)
|
||||
m_reciev_timeout = m_connect_timeout;
|
||||
|
||||
try
|
||||
{
|
||||
m_socket.close();
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
boost::asio::ip::tcp::resolver resolver(m_io_service);
|
||||
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), addr, port);
|
||||
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
|
||||
boost::asio::ip::tcp::resolver::iterator end;
|
||||
if(iterator == end)
|
||||
{
|
||||
LOG_ERROR("Failed to resolve " << addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//boost::asio::ip::tcp::endpoint remote_endpoint(boost::asio::ip::address::from_string(addr.c_str()), port);
|
||||
boost::asio::ip::tcp::endpoint remote_endpoint(*iterator);
|
||||
|
||||
|
||||
m_socket.open(remote_endpoint.protocol());
|
||||
if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" )
|
||||
{
|
||||
boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(addr.c_str()), 0);
|
||||
m_socket.bind(local_endpoint);
|
||||
}
|
||||
|
||||
|
||||
m_deadline.expires_from_now(boost::posix_time::milliseconds(m_connect_timeout));
|
||||
|
||||
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
//m_socket.connect(remote_endpoint);
|
||||
m_socket.async_connect(remote_endpoint, boost::lambda::var(ec) = boost::lambda::_1);
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
if (!ec && m_socket.is_open())
|
||||
{
|
||||
m_connected = true;
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
LOG_PRINT("Some problems at connect, message: " << ec.message(), LOG_LEVEL_3);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_PRINT("Some problems at connect, message: " << er.what(), LOG_LEVEL_4);
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_PRINT("Some fatal problems.", LOG_LEVEL_4);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
bool disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_connected)
|
||||
{
|
||||
m_connected = false;
|
||||
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& /*er*/)
|
||||
{
|
||||
//LOG_ERROR("Some problems at disconnect, message: " << er.what());
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
//LOG_ERROR("Some fatal problems.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
bool send(const std::string& buff)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
|
||||
|
||||
// Set up the variable that receives the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous operation itself. The boost::lambda function
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(buff), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
if (ec)
|
||||
{
|
||||
LOG_PRINT_L3("Problems at write: " << ec.message());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_ERROR("Some problems at connect, message: " << er.what());
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_ERROR("Some fatal problems.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool send(const void* data, size_t sz)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
|
||||
|
||||
// Set up the variable that receives the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous operation itself. The boost::lambda function
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
*/
|
||||
boost::system::error_code ec;
|
||||
|
||||
size_t writen = m_socket.write_some(boost::asio::buffer(data, sz), ec);
|
||||
|
||||
|
||||
|
||||
if (!writen || ec)
|
||||
{
|
||||
LOG_PRINT_L3("Problems at write: " << ec.message());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_ERROR("Some problems at send, message: " << er.what());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_ERROR("Some fatal problems.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_connected()
|
||||
{
|
||||
return m_connected && m_socket.is_open();
|
||||
//TRY_ENTRY()
|
||||
//return m_socket.is_open();
|
||||
//CATCH_ENTRY_L0("is_connected", false)
|
||||
}
|
||||
|
||||
inline
|
||||
bool recv(std::string& buff)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
// Set a deadline for the asynchronous operation. Since this function uses
|
||||
// a composed operation (async_read_until), the deadline applies to the
|
||||
// entire operation, rather than individual reads from the socket.
|
||||
m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
|
||||
|
||||
// Set up the variable that receives the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
//boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous operation itself. The boost::lambda function
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
size_t bytes_transfered = 0;
|
||||
|
||||
handler_obj hndlr(ec, bytes_transfered);
|
||||
|
||||
char local_buff[10000] = {0};
|
||||
//m_socket.async_read_some(boost::asio::buffer(local_buff, sizeof(local_buff)), hndlr);
|
||||
boost::asio::async_read(m_socket, boost::asio::buffer(local_buff, sizeof(local_buff)), boost::asio::transfer_at_least(1), hndlr);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block && !boost::interprocess::ipcdetail::atomic_read32(&m_shutdowned))
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
|
||||
if (ec)
|
||||
{
|
||||
LOG_PRINT_L4("READ ENDS: Connection err_code " << ec.value());
|
||||
if(ec == boost::asio::error::eof)
|
||||
{
|
||||
LOG_PRINT_L4("Connection err_code eof.");
|
||||
//connection closed there, empty
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_PRINT_L3("Problems at read: " << ec.message());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
LOG_PRINT_L4("READ ENDS: Success. bytes_tr: " << bytes_transfered);
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
/*if(!bytes_transfered)
|
||||
return false;*/
|
||||
|
||||
buff.assign(local_buff, bytes_transfered);
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_ERROR("Some problems at read, message: " << er.what());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_ERROR("Some fatal problems at read.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
inline bool recv_n(std::string& buff, boost::int64_t sz)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
// Set a deadline for the asynchronous operation. Since this function uses
|
||||
// a composed operation (async_read_until), the deadline applies to the
|
||||
// entire operation, rather than individual reads from the socket.
|
||||
m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
|
||||
|
||||
// Set up the variable that receives the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
//boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous operation itself. The boost::lambda function
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
|
||||
buff.resize(static_cast<size_t>(sz));
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
size_t bytes_transfered = 0;
|
||||
|
||||
|
||||
handler_obj hndlr(ec, bytes_transfered);
|
||||
|
||||
//char local_buff[10000] = {0};
|
||||
boost::asio::async_read(m_socket, boost::asio::buffer((char*)buff.data(), buff.size()), boost::asio::transfer_at_least(buff.size()), hndlr);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while (ec == boost::asio::error::would_block && !boost::interprocess::ipcdetail::atomic_read32(&m_shutdowned))
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}
|
||||
|
||||
if (ec)
|
||||
{
|
||||
LOG_PRINT_L3("Problems at read: " << ec.message());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
if(bytes_transfered != buff.size())
|
||||
{
|
||||
LOG_ERROR("Transferred missmatch with transfer_at_least value: m_bytes_transferred=" << bytes_transfered << " at_least value=" << buff.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_ERROR("Some problems at read, message: " << er.what());
|
||||
m_connected = false;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_ERROR("Some fatal problems at read.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool shutdown()
|
||||
{
|
||||
m_deadline.cancel();
|
||||
boost::system::error_code ignored_ec;
|
||||
m_socket.cancel(ignored_ec);
|
||||
m_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
|
||||
m_socket.close(ignored_ec);
|
||||
boost::interprocess::ipcdetail::atomic_write32(&m_shutdowned, 1);
|
||||
m_connected = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_connected(bool connected)
|
||||
{
|
||||
m_connected = connected;
|
||||
}
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket& get_socket()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void check_deadline()
|
||||
{
|
||||
// Check whether the deadline has passed. We compare the deadline against
|
||||
// the current time since a new asynchronous operation may have moved the
|
||||
// deadline before this actor had a chance to run.
|
||||
if (m_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now())
|
||||
{
|
||||
// The deadline has passed. The socket is closed so that any outstanding
|
||||
// asynchronous operations are cancelled. This allows the blocked
|
||||
// connect(), read_line() or write_line() functions to return.
|
||||
LOG_PRINT_L3("Timed out socket");
|
||||
m_connected = false;
|
||||
m_socket.close();
|
||||
|
||||
// There is no longer an active deadline. The expiry is set to positive
|
||||
// infinity so that the actor takes no action until a new deadline is set.
|
||||
m_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
// Put the actor back to sleep.
|
||||
m_deadline.async_wait(boost::bind(&blocked_mode_client::check_deadline, this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
boost::asio::io_service m_io_service;
|
||||
boost::asio::ip::tcp::socket m_socket;
|
||||
int m_connect_timeout;
|
||||
int m_reciev_timeout;
|
||||
bool m_initialized;
|
||||
bool m_connected;
|
||||
boost::asio::deadline_timer m_deadline;
|
||||
volatile boost::uint32_t m_shutdowned;
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class async_blocked_mode_client: public blocked_mode_client
|
||||
{
|
||||
public:
|
||||
async_blocked_mode_client():m_send_deadline(blocked_mode_client::m_io_service)
|
||||
{
|
||||
|
||||
// No deadline is required until the first socket operation is started. We
|
||||
// set the deadline to positive infinity so that the actor takes no action
|
||||
// until a specific deadline is set.
|
||||
m_send_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
|
||||
// Start the persistent actor that checks for deadline expiry.
|
||||
check_send_deadline();
|
||||
}
|
||||
~async_blocked_mode_client()
|
||||
{
|
||||
m_send_deadline.cancel();
|
||||
}
|
||||
|
||||
bool shutdown()
|
||||
{
|
||||
blocked_mode_client::shutdown();
|
||||
m_send_deadline.cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
bool send(const void* data, size_t sz)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
m_send_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
|
||||
|
||||
// Set up the variable that receives the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
boost::system::error_code ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous operation itself. The boost::lambda function
|
||||
// object is used as a callback and will update the ec variable when the
|
||||
// operation completes. The blocking_udp_client.cpp example shows how you
|
||||
// can use boost::bind rather than boost::lambda.
|
||||
boost::asio::async_write(m_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
while(ec == boost::asio::error::would_block)
|
||||
{
|
||||
m_io_service.run_one();
|
||||
}*/
|
||||
|
||||
boost::system::error_code ec;
|
||||
|
||||
size_t writen = m_socket.write_some(boost::asio::buffer(data, sz), ec);
|
||||
|
||||
if (!writen || ec)
|
||||
{
|
||||
LOG_PRINT_L3("Problems at write: " << ec.message());
|
||||
return false;
|
||||
}else
|
||||
{
|
||||
m_send_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
}
|
||||
|
||||
catch(const boost::system::system_error& er)
|
||||
{
|
||||
LOG_ERROR("Some problems at connect, message: " << er.what());
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
LOG_ERROR("Some fatal problems.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
boost::asio::deadline_timer m_send_deadline;
|
||||
|
||||
void check_send_deadline()
|
||||
{
|
||||
// Check whether the deadline has passed. We compare the deadline against
|
||||
// the current time since a new asynchronous operation may have moved the
|
||||
// deadline before this actor had a chance to run.
|
||||
if (m_send_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now())
|
||||
{
|
||||
// The deadline has passed. The socket is closed so that any outstanding
|
||||
// asynchronous operations are cancelled. This allows the blocked
|
||||
// connect(), read_line() or write_line() functions to return.
|
||||
LOG_PRINT_L3("Timed out socket");
|
||||
m_socket.close();
|
||||
|
||||
// There is no longer an active deadline. The expiry is set to positive
|
||||
// infinity so that the actor takes no action until a new deadline is set.
|
||||
m_send_deadline.expires_at(boost::posix_time::pos_infin);
|
||||
}
|
||||
|
||||
// Put the actor back to sleep.
|
||||
m_send_deadline.async_wait(boost::bind(&async_blocked_mode_client::check_send_deadline, this));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue