YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
TcpConnector.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2010 Anne van Rossum <anne@almende.com>
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <yarp/conf/system.h>
8#ifndef YARP_HAS_ACE
9
11
12// General files
13# include <yarp/os/Log.h>
16
17# include <cstdio>
18# include <fcntl.h>
19# include <iostream>
20# include <sys/socket.h>
21
22using namespace yarp::os::impl;
23using namespace yarp::os;
24
25namespace {
26YARP_OS_LOG_COMPONENT(TCPCONNECTOR_POSIX, "yarp.os.impl.TcpConnector.posix")
27}
28
29/* **************************************************************************************
30 * Implementation of TcpConnector
31 * **************************************************************************************/
32
33TcpConnector::TcpConnector() = default;
34
35TcpConnector::~TcpConnector() = default;
36
37int TcpConnector::open(TcpStream& stream)
38{
39 if ((stream.get_handle() == -1) && (stream.open() == -1)) {
40 return -1;
41 }
42 return 0;
43}
44
48int TcpConnector::connect(TcpStream& new_stream, const Contact& address, YARP_timeval* timeout)
49{
50 // printf("TCP/IP start in client mode\n");
51 // sockets.set_as_client();
52 // sockets.set_client_sockfd(sockfd);
53 if (open(new_stream) == -1) {
54 return -1;
55 }
56
57 // Write sockaddr struct with given address...
59 servAddr.sin_addr.s_addr = INADDR_ANY;
60 servAddr.sin_family = AF_INET;
61 servAddr.sin_port = htons(address.getPort());
62 memset(servAddr.sin_zero, '\0', sizeof servAddr.sin_zero);
63
64 struct hostent* hostInfo = yarp::os::impl::gethostbyname(address.getHost().c_str());
65 if (hostInfo) {
66 bcopy(hostInfo->h_addr, reinterpret_cast<char*>(&servAddr.sin_addr), hostInfo->h_length);
67 } else {
68 inet_pton(AF_INET, address.getHost().c_str(), &servAddr.sin_addr);
69 }
70
71 auto handle = new_stream.get_handle();
72
73 yAssert(handle != -1);
74
75 int res;
76 long arg;
78 int valopt;
80
81 // Set non-blocking
82 if ((arg = fcntl(handle, F_GETFL, NULL)) < 0) {
83 yCError(TCPCONNECTOR_POSIX, "connect fail: Error fcntl(..., F_GETFL): %d, %s", errno, strerror(errno));
84 return -1;
85 }
86 arg |= O_NONBLOCK;
87 if (fcntl(handle, F_SETFL, arg) < 0) {
88 yCError(TCPCONNECTOR_POSIX, "connect fail: Error fcntl(..., F_SETFL): %d, %s", errno, strerror(errno));
89 return -1;
90 }
91 // Trying to connect with timeout
92 res = ::connect(handle, reinterpret_cast<sockaddr*>(&servAddr), sizeof(servAddr));
93
94 if (res < 0) {
95 if (errno == EINPROGRESS) {
96 FD_ZERO(&myset);
98 res = select(handle + 1, nullptr, &myset, nullptr, timeout);
99 if (res < 0 && errno != EINTR) {
100 yCError(TCPCONNECTOR_POSIX, "connect fail: Error connecting: %d, %s", errno, strerror(errno));
101 res = -1;
102 } else if (res > 0) {
103 res = 0;
104 // Socket selected for write
105 lon = sizeof(int);
106 if (getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&valopt), &lon) < 0) {
107 yCError(TCPCONNECTOR_POSIX, "connect fail: Error in getsockopt(): %d, %s", errno, strerror(errno));
108 res = -1;
109 }
110 // Check the value returned...
111 if (valopt) {
112 // connect fail: Error in delayed connection() -> the port doesn't exist
113 res = -1;
114 }
115 } else {
116 yCError(TCPCONNECTOR_POSIX, "connect fail: Timeout in select() - Cancelling!: %d, %s", errno, strerror(errno));
117 res = -1;
118 }
119 } else {
120 yCError(TCPCONNECTOR_POSIX, "connect fail: Error connecting: %d, %s", errno, strerror(errno));
121 res = -1;
122 }
123 }
124
125 if (res != 0) {
126 char buf[INET_ADDRSTRLEN];
128 "Connect [handle=%d] at %s:%d",
129 new_stream.get_handle(),
130 inet_ntop(AF_INET, &servAddr.sin_addr, buf, INET_ADDRSTRLEN),
131 servAddr.sin_port);;
132 return -1;
133 }
134
135 // Set to blocking mode again...
136 if ((arg = fcntl(handle, F_GETFL, nullptr)) < 0) {
137 yCError(TCPCONNECTOR_POSIX, "connect fail: Error fcntl(..., F_GETFL): %d, %s", errno, strerror(errno));
138 return -1;
139 }
140 arg &= (~O_NONBLOCK);
141 if (fcntl(handle, F_SETFL, arg) < 0) {
142 yCError(TCPCONNECTOR_POSIX, "connect fail: Error fcntl(..., F_SETFL): %d, %s", errno, strerror(errno));
143 return -1;
144 }
145
146 return res;
147}
148
149#endif
#define yAssert(x)
Definition Log.h:388
A mini-server for performing network communication in the background.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition Contact.cpp:239
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition Contact.cpp:228
#define yCError(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.