Enable TCP keepalive on sockets so that we can detect connection "hangs" that can happen when wireless goes out
This commit is contained in:
parent
46d2b95528
commit
995c8bbba4
|
@ -55,6 +55,9 @@ class PollSet;
|
|||
*/
|
||||
class TransportTCP : public Transport
|
||||
{
|
||||
public:
|
||||
static bool s_use_keepalive_;
|
||||
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
|
@ -95,6 +98,7 @@ public:
|
|||
int getServerPort() { return server_port_; }
|
||||
|
||||
void setNoDelay(bool nodelay);
|
||||
void setKeepAlive(bool use, uint32_t idle, uint32_t interval, uint32_t count);
|
||||
|
||||
// overrides from Transport
|
||||
virtual int32_t read(uint8_t* buffer, uint32_t size);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "ros/callback_queue.h"
|
||||
#include "ros/param.h"
|
||||
#include "ros/rosout_appender.h"
|
||||
#include "ros/transport/transport_tcp.h"
|
||||
|
||||
#include "roscpp/GetLoggers.h"
|
||||
#include "roscpp/SetLoggerLevel.h"
|
||||
|
@ -266,6 +267,8 @@ void start()
|
|||
g_started = true;
|
||||
g_ok = true;
|
||||
|
||||
param::param("/tcp_keepalive", TransportTCP::s_use_keepalive_, TransportTCP::s_use_keepalive_);
|
||||
|
||||
PollManager::instance()->addPollThreadListener(checkForShutdown);
|
||||
XMLRPCManager::instance()->bind("shutdown", shutdownCallback);
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
namespace ros
|
||||
{
|
||||
|
||||
bool TransportTCP::s_use_keepalive_ = true;
|
||||
|
||||
TransportTCP::TransportTCP(PollSet* poll_set, int flags)
|
||||
: sock_(-1)
|
||||
, closed_(false)
|
||||
|
@ -95,6 +97,8 @@ bool TransportTCP::initializeSocket()
|
|||
}
|
||||
}
|
||||
|
||||
setKeepAlive(s_use_keepalive_, 60, 10, 9);
|
||||
|
||||
if (is_server_)
|
||||
{
|
||||
cached_remote_host_ = "TCPServer Socket";
|
||||
|
@ -144,6 +148,48 @@ void TransportTCP::setNoDelay(bool nodelay)
|
|||
}
|
||||
}
|
||||
|
||||
void TransportTCP::setKeepAlive(bool use, uint32_t idle, uint32_t interval, uint32_t count)
|
||||
{
|
||||
if (use)
|
||||
{
|
||||
ROSCPP_LOG_DEBUG("Enabling TCP Keepalive on socket [%d]", sock_);
|
||||
|
||||
int val = 1;
|
||||
if (setsockopt(sock_, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0)
|
||||
{
|
||||
ROS_ERROR("setsockopt failed to set SO_KEEPALIVE on socket [%d] [%s]", sock_, cached_remote_host_.c_str());
|
||||
}
|
||||
|
||||
val = idle;
|
||||
if (setsockopt(sock_, SOL_TCP, TCP_KEEPIDLE, &val, sizeof(val)) != 0)
|
||||
{
|
||||
ROS_ERROR("setsockopt failed to set TCP_KEEPIDLE on socket [%d] [%s]", sock_, cached_remote_host_.c_str());
|
||||
}
|
||||
|
||||
val = interval;
|
||||
if (setsockopt(sock_, SOL_TCP, TCP_KEEPINTVL, &val, sizeof(val)) != 0)
|
||||
{
|
||||
ROS_ERROR("setsockopt failed to set TCP_KEEPINTVL on socket [%d] [%s]", sock_, cached_remote_host_.c_str());
|
||||
}
|
||||
|
||||
val = count;
|
||||
if (setsockopt(sock_, SOL_TCP, TCP_KEEPCNT, &val, sizeof(val)) != 0)
|
||||
{
|
||||
ROS_ERROR("setsockopt failed to set TCP_KEEPCNT on socket [%d] [%s]", sock_, cached_remote_host_.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ROSCPP_LOG_DEBUG("Disabling TCP Keepalive on socket [%d]", sock_);
|
||||
|
||||
int val = 0;
|
||||
if (setsockopt(sock_, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) != 0)
|
||||
{
|
||||
ROS_ERROR("setsockopt failed to set SO_KEEPALIVE on socket [%d] [%s]", sock_, cached_remote_host_.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TransportTCP::connect(const std::string& host, int port)
|
||||
{
|
||||
sock_ = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
|
Loading…
Reference in New Issue