diff --git a/include/fc/network/udp_socket.hpp b/include/fc/network/udp_socket.hpp index cef6eb6..65d1107 100644 --- a/include/fc/network/udp_socket.hpp +++ b/include/fc/network/udp_socket.hpp @@ -23,8 +23,9 @@ namespace fc { void set_receive_buffer_size( size_t s ); void bind( const fc::ip::endpoint& ); size_t receive_from( char* b, size_t l, fc::ip::endpoint& from ); - size_t receive_from( std::shared_ptr b, size_t l, fc::ip::endpoint& from ); + size_t receive_from( const std::shared_ptr& b, size_t l, fc::ip::endpoint& from ); size_t send_to( const char* b, size_t l, const fc::ip::endpoint& to ); + size_t send_to( const std::shared_ptr& b, size_t l, const fc::ip::endpoint& to ); void close(); void set_multicast_enable_loopback( bool ); diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 07163e2..d786e4f 100644 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -57,9 +57,11 @@ namespace fc for( auto ep : eps ) { ilog( "sending request to ${ep}", ("ep",ep) ); - std::array send_buf { {010,0,0,0,0,0,0,0,0} }; + std::shared_ptr send_buffer(new char[48], [](char* p){ delete[] p; }); + std::array packet_to_send { {010,0,0,0,0,0,0,0,0} }; + memcpy(send_buffer.get(), packet_to_send.data(), packet_to_send.size()); _last_request_time = fc::time_point::now(); - _sock.send_to( (const char*)send_buf.data(), send_buf.size(), ep ); + _sock.send_to( send_buffer, packet_to_send.size(), ep ); break; } } diff --git a/src/network/udp_socket.cpp b/src/network/udp_socket.cpp index 9a1745a..514e148 100644 --- a/src/network/udp_socket.cpp +++ b/src/network/udp_socket.cpp @@ -44,25 +44,45 @@ namespace fc { } } - size_t udp_socket::send_to( const char* b, size_t l, const ip::endpoint& to ) { - try { - return my->_sock.send_to( boost::asio::buffer(b, l), to_asio_ep(to) ); - } catch( const boost::system::system_error& e ) { - if( e.code() == boost::asio::error::would_block ) { - promise::ptr p(new promise("udp_socket::send_to")); - my->_sock.async_send_to( boost::asio::buffer(b,l), to_asio_ep(to), - [=]( const boost::system::error_code& ec, size_t bt ) { - if( !ec ) p->set_value(bt); - else - p->set_exception( fc::exception_ptr( new fc::exception( - FC_LOG_MESSAGE( error, "${message} ", - ("message", boost::system::system_error(ec).what())) ) ) ); - }); - return p->wait(); - } + size_t udp_socket::send_to( const char* buffer, size_t length, const ip::endpoint& to ) + { + try + { + return my->_sock.send_to( boost::asio::buffer(buffer, length), to_asio_ep(to) ); + } + catch( const boost::system::system_error& e ) + { + if( e.code() != boost::asio::error::would_block ) throw; } + + promise::ptr completion_promise(new promise("udp_socket::send_to")); + my->_sock.async_send_to( boost::asio::buffer(buffer, length), to_asio_ep(to), + asio::detail::read_write_handler(completion_promise) ); + + return completion_promise->wait(); } + + size_t udp_socket::send_to( const std::shared_ptr& buffer, size_t length, + const fc::ip::endpoint& to ) + { + try + { + return my->_sock.send_to( boost::asio::buffer(buffer.get(), length), to_asio_ep(to) ); + } + catch( const boost::system::system_error& e ) + { + if( e.code() != boost::asio::error::would_block ) + throw; + } + + promise::ptr completion_promise(new promise("udp_socket::send_to")); + my->_sock.async_send_to( boost::asio::buffer(buffer.get(), length), to_asio_ep(to), + asio::detail::read_write_handler_with_buffer(completion_promise, buffer) ); + + return completion_promise->wait(); + } + void udp_socket::open() { my->_sock.open( boost::asio::ip::udp::v4() ); my->_sock.non_blocking(true); @@ -74,12 +94,13 @@ namespace fc { my->_sock.bind( to_asio_ep(e) ); } - size_t udp_socket::receive_from( std::shared_ptr receive_buffer, size_t receive_buffer_length, fc::ip::endpoint& from ) + size_t udp_socket::receive_from( const std::shared_ptr& receive_buffer, size_t receive_buffer_length, fc::ip::endpoint& from ) { try { boost::asio::ip::udp::endpoint boost_from_endpoint; - size_t bytes_read = my->_sock.receive_from( boost::asio::buffer(receive_buffer.get(), receive_buffer_length), boost_from_endpoint ); + size_t bytes_read = my->_sock.receive_from( boost::asio::buffer(receive_buffer.get(), receive_buffer_length), + boost_from_endpoint ); from = to_fc_ep(boost_from_endpoint); return bytes_read; } @@ -104,7 +125,8 @@ namespace fc { try { boost::asio::ip::udp::endpoint boost_from_endpoint; - size_t bytes_read = my->_sock.receive_from( boost::asio::buffer(receive_buffer, receive_buffer_length), boost_from_endpoint ); + size_t bytes_read = my->_sock.receive_from( boost::asio::buffer(receive_buffer, receive_buffer_length), + boost_from_endpoint ); from = to_fc_ep(boost_from_endpoint); return bytes_read; }