YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
SocketTwoWayStream.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-FileCopyrightText: 2006 Anne van Rossum <anne@almende.com>
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
9
15
16#ifdef YARP_HAS_ACE
17# include <ace/INET_Addr.h>
18# include <ace/os_include/netinet/os_tcp.h>
19// In one the ACE headers there is a definition of "main" for WIN32
20# ifdef main
21# undef main
22# endif
23#elif defined(__unix__) || defined(__APPLE__)
24# include <netinet/tcp.h>
25#endif
26
27using namespace yarp::os;
28using namespace yarp::os::impl;
29
30YARP_OS_LOG_COMPONENT(SOCKETTWOWAYSTREAM, "yarp.os.impl.SocketTwoWayStream")
31
33{
34 if (address.getPort() == -1) {
35 return -1;
36 }
37 std::string host = address.getHost();
38 yarp::os::impl::TcpConnector connector;
39#ifdef YARP_HAS_ACE
40 if (address.getHost() == "localhost") {
41 // ACE does not like localhost. At all.
43 }
44 ACE_INET_Addr addr(address.getPort(), host.c_str());
46 YARP_timeval* timeout = nullptr;
47 if (address.hasTimeout()) {
48 openTimeout.set(address.getTimeout());
49 timeout = &openTimeout;
50 }
51 int result = connector.connect(stream, addr, timeout, ACE_Addr::sap_any, 1);
52#else
53 int result;
54
55 if (address.hasTimeout()) {
56 YARP_timeval timeout;
57 /* set timeout seconds and microseconds */
58 timeout.tv_sec = static_cast<int>(address.getTimeout());
59 timeout.tv_usec = (address.getTimeout() - timeout.tv_sec) * 1000000;
60 result = connector.connect(stream, address, &timeout);
61 } else {
62 result = connector.connect(stream, address, nullptr);
63 }
64
65
66#endif
67 if (result >= 0) {
68 happy = true;
69 } else {
71 "TCP connection to tcp:/%s failed to open",
72 address.toURI(false).c_str());
73 }
74 updateAddresses();
75 return result;
76}
77
78int SocketTwoWayStream::open(yarp::os::impl::TcpAcceptor& acceptor)
79{
80 int result = acceptor.accept(stream);
81 if (result >= 0) {
82 happy = true;
83 }
84 updateAddresses();
85 return result;
86}
87
88
89void SocketTwoWayStream::updateAddresses()
90{
91 int one = 1;
92 stream.set_option(IPPROTO_TCP, TCP_NODELAY, &one, sizeof(int));
93#ifdef YARP_HAS_ACE
94 ACE_INET_Addr local;
95 ACE_INET_Addr remote;
96 stream.get_local_addr(local);
97 stream.get_remote_addr(remote);
98
99 char localHostAddress[256];
100 char remoteHostAddress[256];
101 local.get_host_addr(localHostAddress, 256);
102 remote.get_host_addr(remoteHostAddress, 256);
103 localAddress = Contact(localHostAddress, local.get_port_number());
104 remoteAddress = Contact(remoteHostAddress, remote.get_port_number());
105#else
106 struct sockaddr local;
107 struct sockaddr remote;
108 memset(&local, 0, sizeof(local));
109 memset(&remote, 0, sizeof(remote));
110 stream.get_local_addr(local);
111 stream.get_remote_addr(remote);
112 if (local.sa_family == AF_INET || local.sa_family == AF_INET6) {
113 char* localHostAddress = new char[local.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN];
114 char* remoteHostAddress = new char[remote.sa_family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN];
115 const char* ret = nullptr;
116 ret = inet_ntop(local.sa_family,
117 (local.sa_family == AF_INET ? reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in*>(&local)->sin_addr) : reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in6*>(&local)->sin6_addr)),
120 if (ret) {
121 localAddress = Contact(localHostAddress, ntohs(reinterpret_cast<struct sockaddr_in*>(&local)->sin_port));
122 } else {
123 yCError(SOCKETTWOWAYSTREAM, "SocketTwoWayStream::updateAddresses failed getting local address");
124 }
125 ret = inet_ntop(remote.sa_family,
126 (remote.sa_family == AF_INET ? reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in*>(&remote)->sin_addr) : reinterpret_cast<void*>(&reinterpret_cast<struct sockaddr_in6*>(&remote)->sin6_addr)),
129 if (ret) {
130 remoteAddress = Contact(remoteHostAddress, ntohs(reinterpret_cast<struct sockaddr_in*>(&remote)->sin_port));
131 } else {
132 yCError(SOCKETTWOWAYSTREAM, "SocketTwoWayStream::updateAddresses failed getting local address");
133 }
134 delete[] localHostAddress;
135 delete[] remoteHostAddress;
136 } else {
137 yCError(SOCKETTWOWAYSTREAM, "Unknown address type");
138 }
139#endif
140
141 yCDebug(SOCKETTWOWAYSTREAM, "updateAddresses: local address = %s", localAddress.getHost().c_str());
142 yCDebug(SOCKETTWOWAYSTREAM, "updateAddresses: remote address = %s", remoteAddress.getHost().c_str());
143}
144
146{
147 yCDebug(SOCKETTWOWAYSTREAM, "Setting tos = %d", tos);
148 return (stream.set_option(IPPROTO_IP, IP_TOS, &tos, static_cast<int>(sizeof(tos))) == 0);
149}
150
152{
153 int tos = -1;
154 int optlen;
155 stream.get_option(IPPROTO_IP, IP_TOS, &tos, &optlen);
156 return tos;
157}
bool ret
const yarp::os::LogComponent & SOCKETTWOWAYSTREAM()
A mini-server for performing network communication in the background.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition Contact.cpp:228
static std::string getHostName(bool prefer_loopback=false, const std::string &seed="")
A stream abstraction for socket communication.
#define yCError(component,...)
#define yCDebug(component,...)
#define YARP_OS_LOG_COMPONENT(name, name_string)
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.