Add to tcp_socket to enable TCP keepalives

This commit is contained in:
Eric Frias 2014-04-09 18:29:59 -04:00
parent 23cd85ef87
commit 85a9da6f27
2 changed files with 40 additions and 1 deletions

View file

@ -2,6 +2,7 @@
#include <fc/utility.hpp>
#include <fc/fwd.hpp>
#include <fc/io/iostream.hpp>
#include <fc/time.hpp>
namespace fc {
namespace ip { class endpoint; }
@ -13,6 +14,7 @@ namespace fc {
void connect_to( const fc::ip::endpoint& remote_endpoint );
void connect_to( const fc::ip::endpoint& remote_endpoint, const fc::ip::endpoint& local_endpoint );
void enable_keep_alives(const fc::microseconds& interval);
fc::ip::endpoint remote_endpoint()const;
void get( char& c )
@ -58,7 +60,6 @@ namespace fc {
void listen( uint16_t port );
void listen( const fc::ip::endpoint& ep );
uint16_t get_port()const;
private:
// non copyable
tcp_server( const tcp_server& );

View file

@ -6,6 +6,10 @@
#include <fc/io/stdio.hpp>
#include <fc/exception/exception.hpp>
#if defined _WIN32 || defined WIN32 || defined OS_WIN64 || defined _WIN64 || defined WIN64 || defined WINNT
# include <MSTcpIP.h>
#endif
namespace fc {
class tcp_socket::impl {
@ -64,6 +68,40 @@ namespace fc {
fc::asio::tcp::connect(my->_sock, fc::asio::tcp::endpoint( boost::asio::ip::address_v4(remote_endpoint.get_address()), remote_endpoint.port() ) );
}
void tcp_socket::enable_keep_alives(const fc::microseconds& interval)
{
if (interval.count())
{
boost::asio::socket_base::keep_alive option(true);
my->_sock.set_option(option);
#if defined _WIN32 || defined WIN32 || defined OS_WIN64 || defined _WIN64 || defined WIN64 || defined WINNT
struct tcp_keepalive keepalive_settings;
keepalive_settings.onoff = 1;
keepalive_settings.keepalivetime = interval.count() / fc::milliseconds(1).count();
keepalive_settings.keepaliveinterval = interval.count() / fc::milliseconds(1).count();
DWORD dwBytesRet = 0;
if (WSAIoctl(my->_sock.native(), SIO_KEEPALIVE_VALS, &keepalive_settings, sizeof(keepalive_settings),
NULL, 0, &dwBytesRet, NULL, NULL) == SOCKET_ERROR)
wlog("Error setting TCP keepalive values");
#else
// This should work for modern Linuxes and for OSX >= Mountain Lion
int timeout_sec = interval.count() / fc::seconds(1).count();
if (setsockopt(my->_sock.native(), SOL_TCP, TCP_KEEPIDLE,
(char*)&timeout_sec, sizeof(timeout_sec)) < 0)
wlog("Error setting TCP keepalive idle time");
if (setsockopt(my->_sock.native(), SOL_TCP, TCP_KEEPINTVL,
(char*)&timeout_sec, sizeof(timeout_sec)) < 0)
wlog("Error setting TCP keepalive interval");
#endif
}
else
{
boost::asio::socket_base::keep_alive option(false);
my->_sock.set_option(option);
}
}
class tcp_server::impl {
public:
impl(uint16_t port)