Skip to content

Commit 84d65c7

Browse files
authored
Use tcp_nodelay on socket server (#537)
The sockets we use in this library should be optimized for real-time communication, not for throughput. Therefore, they should use tcp_nodelay by default.
1 parent b437116 commit 84d65c7

3 files changed

Lines changed: 33 additions & 8 deletions

File tree

include/ur_client_library/comm/socket_t.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ typedef int socket_t;
7171
# define MSG_NOSIGNAL 0
7272
#endif
7373

74+
#include "ur_client_library/log.h"
75+
7476
/*!
7577
* \brief Get the last socket error as an std::error_code
7678
*
@@ -92,3 +94,14 @@ inline std::system_error makeSocketError(const std::string& message)
9294
{
9395
return std::system_error(getLastSocketErrorCode(), message);
9496
}
97+
98+
inline void setSocketOptionAndWarnOnError(socket_t socket, int level, int optname, const void* optval,
99+
unsigned int optlen, const std::string& option_name)
100+
{
101+
int result = ur_setsockopt(socket, level, optname, optval, optlen);
102+
if (result != 0)
103+
{
104+
std::error_code error_code = getLastSocketErrorCode();
105+
URCL_LOG_WARN("Failed to set socket option %s: %s", option_name.c_str(), error_code.message().c_str());
106+
}
107+
}

src/comm/tcp_server.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
*/
2727
//----------------------------------------------------------------------
2828

29+
#ifndef _WIN32
30+
# include <netinet/tcp.h>
31+
#endif
2932
#include <ur_client_library/log.h>
3033
#include <ur_client_library/comm/tcp_server.h>
3134

@@ -67,11 +70,11 @@ void TCPServer::init()
6770
{
6871
throw makeSocketError("Failed to create socket endpoint");
6972
}
70-
int flag = 1;
73+
constexpr int flag = 1;
7174
#ifndef _WIN32
72-
ur_setsockopt(listen_fd_, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
75+
setSocketOptionAndWarnOnError(listen_fd_, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag), "SO_REUSEADDR");
7376
#endif
74-
ur_setsockopt(listen_fd_, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(int));
77+
setSocketOptionAndWarnOnError(listen_fd_, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof(flag), "SO_KEEPALIVE");
7578

7679
URCL_LOG_DEBUG("Created socket with FD %d", (int)listen_fd_);
7780

@@ -257,6 +260,13 @@ void TCPServer::handleConnect()
257260
ur_close(client_fd);
258261
}
259262
}
263+
264+
if (accepted)
265+
{
266+
constexpr int flag = 1;
267+
setSocketOptionAndWarnOnError(client_fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag), "TCP_NODELAY");
268+
}
269+
260270
{
261271
std::lock_guard<std::mutex> lk(callback_mutex_);
262272
if (new_connection_callback_ && accepted)

src/comm/tcp_socket.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <cstring>
2525
#include <sstream>
2626
#include <thread>
27+
#include "ur_client_library/comm/socket_t.h"
2728

2829
#ifndef _WIN32
2930
# include <arpa/inet.h>
@@ -52,22 +53,23 @@ TCPSocket::~TCPSocket()
5253

5354
void TCPSocket::setupOptions()
5455
{
55-
int flag = 1;
56-
ur_setsockopt(socket_fd_, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
56+
constexpr int flag = 1;
57+
setSocketOptionAndWarnOnError(socket_fd_, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag), "TCP_NODELAY");
5758

5859
// macOS does not have TCP_QUICKACK
5960
#ifdef TCP_QUICKACK
60-
ur_setsockopt(socket_fd_, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(int));
61+
setSocketOptionAndWarnOnError(socket_fd_, IPPROTO_TCP, TCP_QUICKACK, &flag, sizeof(flag), "TCP_QUICKACK");
6162
#endif
6263

6364
if (recv_timeout_ != nullptr)
6465
{
6566
#ifdef _WIN32
6667
DWORD value = recv_timeout_->tv_sec * 1000;
6768
value += recv_timeout_->tv_usec / 1000;
68-
ur_setsockopt(socket_fd_, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value));
69+
setSocketOptionAndWarnOnError(socket_fd_, SOL_SOCKET, SO_RCVTIMEO, &value, sizeof(value), "SO_RCVTIMEO");
6970
#else
70-
ur_setsockopt(socket_fd_, SOL_SOCKET, SO_RCVTIMEO, recv_timeout_.get(), sizeof(timeval));
71+
setSocketOptionAndWarnOnError(socket_fd_, SOL_SOCKET, SO_RCVTIMEO, recv_timeout_.get(), sizeof(timeval),
72+
"SO_RCVTIMEO");
7173
#endif
7274
}
7375
}

0 commit comments

Comments
 (0)