30 # include <arpa/inet.h>
31 # include <netinet/tcp.h>
46 ::WSAStartup(MAKEWORD(1, 1), &data);
72 bool TCPSocket::setup(
const std::string& host,
const int port,
const size_t max_num_tries,
73 const std::chrono::milliseconds reconnection_time)
76 auto reconnection_time_resolved = reconnection_time;
79 URCL_LOG_WARN(
"TCPSocket::setup(): Reconnection time was modified using `setReconnectionTime()` which is "
80 "deprecated. Please change your code to set reconnection_time through the `setup()` method "
81 "directly. The value passed to this function will be ignored.");
88 URCL_LOG_DEBUG(
"Setting up connection: %s:%d", host.c_str(), port);
93 const char* host_name = host.empty() ? nullptr : host.c_str();
94 std::string service = std::to_string(port);
95 struct addrinfo hints, *result;
96 std::memset(&hints, 0,
sizeof(hints));
98 hints.ai_family = AF_UNSPEC;
99 hints.ai_socktype = SOCK_STREAM;
100 hints.ai_flags = AI_PASSIVE;
102 size_t connect_counter = 0;
103 bool connected =
false;
106 if (getaddrinfo(host_name, service.c_str(), &hints, &result) != 0)
108 URCL_LOG_ERROR(
"Failed to get address for %s:%d", host.c_str(), port);
112 for (
struct addrinfo* p = result; p !=
nullptr; p = p->ai_next)
114 socket_fd_ = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
123 freeaddrinfo(result);
128 if (++connect_counter >= max_num_tries && max_num_tries > 0)
130 URCL_LOG_ERROR(
"Failed to establish connection for %s:%d after %d tries", host.c_str(), port, max_num_tries);
135 std::stringstream ss;
136 ss <<
"Failed to connect to robot on IP " << host_name <<
":" << port
137 <<
". Please check that the robot is booted and reachable on " << host_name <<
". Retrying in "
138 << std::chrono::duration_cast<std::chrono::duration<float>>(reconnection_time_resolved).count()
141 std::this_thread::sleep_for(reconnection_time_resolved);
147 URCL_LOG_DEBUG(
"Connection established for %s:%d", host.c_str(), port);
164 socklen_t len =
sizeof(name);
165 int res = ::getsockname(
socket_fd_, (sockaddr*)&name, &len);
170 return std::string();
174 inet_ntop(AF_INET, &name.sin_addr, buf,
sizeof(buf));
175 return std::string(buf);
184 return read((uint8_t*)character, 1, read_chars);
195 ssize_t res = ::recv(
socket_fd_,
reinterpret_cast<char*
>(buf),
static_cast<const socklen_t
>(buf_len), 0);
197 ssize_t res = ::recv(
socket_fd_, buf, buf_len, 0);
209 int code = ::WSAGetLastError();
210 if (code != WSAETIMEDOUT && code != WSAEWOULDBLOCK)
215 if (!(errno == EAGAIN || errno == EWOULDBLOCK))
224 read =
static_cast<size_t>(res);
238 size_t remaining = buf_len;
241 while (written < buf_len)
244 ::send(
socket_fd_,
reinterpret_cast<const char*
>(buf + written),
static_cast<socklen_t
>(remaining), 0);
252 written +=
static_cast<size_t>(sent);
271 URCL_LOG_ERROR(
"Calling setReconnectionTime is deprecated. Reconnection timeout is passed to the setup method "