YARP
Yet Another Robot Platform
TcpAcceptor.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 
10 // General files
11 
16 
17 using namespace yarp::os::impl;
18 using namespace yarp::os;
19 
20 #define BACKLOG 1
21 
22 namespace {
23 YARP_OS_LOG_COMPONENT(TCPACCEPTOR_POSIX, "yarp.os.impl.TcpAcceptor.posix")
24 }
25 
29 void sigchld_handler(int /*s*/)
30 {
31  while(waitpid(-1, nullptr, WNOHANG) > 0) {}
32 }
33 
34 
35 /* **************************************************************************************
36  * Implementation of TcpAcceptor
37  * **************************************************************************************/
38 
39 int TcpAcceptor::open(const Contact& address)
40 {
41  yCDebug(TCPACCEPTOR_POSIX, "TCP/IP start in server mode");
42  set_handle(socket(AF_INET, SOCK_STREAM, 0));
43  if (get_handle() < 0) {
44  yCError(TCPACCEPTOR_POSIX, "At TcpAcceptor::open there was an error: %d, %s", errno, strerror(errno));
45  return -1;
46  }
47 
48  int yes=1;
49  if (setsockopt(get_handle(), SOL_SOCKET, SO_REUSEADDR, &yes,
50  sizeof(int)) == -1) {
51  yCError(TCPACCEPTOR_POSIX, "At TcpAcceptor::open there was an error: %d, %s", errno, strerror(errno));
52  return -1;
53  }
54 
55  return shared_open(address);
56 }
57 
61 int TcpAcceptor::shared_open(const Contact& address)
62 {
63  struct sockaddr_in servAddr;
64  servAddr.sin_addr.s_addr = INADDR_ANY;
65  servAddr.sin_family = AF_INET;
66  servAddr.sin_port = htons((address.getPort()>0)?address.getPort():0);
67  inet_pton(AF_INET, address.getHost().c_str(), &servAddr.sin_addr);
68  memset(servAddr.sin_zero, '\0', sizeof servAddr.sin_zero);
69 
70  if (bind(get_handle(), (struct sockaddr *)&servAddr, sizeof (struct sockaddr)) < 0) {
71  yCError(TCPACCEPTOR_POSIX, "At bind(sockfd) there was an error: %d, %s", errno, strerror(errno));
72  return -1;
73  }
74 
75  if (listen(get_handle(), BACKLOG) < 0) {
76  yCError(TCPACCEPTOR_POSIX, "At listen(sockfd) there was an error: %d, %s", errno, strerror(errno));
77  return -1;
78  }
79 
80  struct sigaction sa;
81  sa.sa_handler = sigchld_handler;
82  sigemptyset(&sa.sa_mask);
83  sa.sa_flags = SA_RESTART;
84  if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
85  yCError(TCPACCEPTOR_POSIX, "At sigaction(address) there was an error: %d, %s", errno, strerror(errno));
86  return -1;
87  }
88 
89  struct sockaddr_in sin;
90  socklen_t addrlen = sizeof(sin);
91  if (getsockname(get_handle(), (struct sockaddr *)&sin, &addrlen) == 0 &&
92  sin.sin_family == AF_INET &&
93  addrlen == sizeof(sin)) {
94  port_number = static_cast<int>(ntohs(sin.sin_port));
95  } else {
96  yCError(TCPACCEPTOR_POSIX, "At getsockname(address) there was an error: %d, %s", errno, strerror(errno));
97  return -1;
98  }
99 
100  return 1;
101 }
102 
103 
107 int TcpAcceptor::accept(TcpStream &new_stream)
108 {
109  sockaddr* addr = nullptr;
110  int len = 0;
111  int* len_ptr = &len;
112 
113  new_stream.set_handle(::accept(get_handle(), reinterpret_cast<struct sockaddr*>(&addr), reinterpret_cast<socklen_t*>(len_ptr)));
114  if (new_stream.get_handle() < 0) {
115  yCError(TCPACCEPTOR_POSIX, "At accept(sockfd) there was an error: %d, %s", errno, strerror(errno));
116  return -1;
117  }
118 
119  return 1;
120 }
121 
122 int TcpAcceptor::close()
123 {
124  int result = 0;
125 
126  if (get_handle() != -1) {
127  result = ::close(get_handle());
128  set_handle (-1);
129  }
130  return result;
131 }
132 
133 #endif
void sigchld_handler(int)
An error handler that reaps the zombies.
Definition: TcpAcceptor.cpp:29
#define BACKLOG
Definition: TcpAcceptor.cpp:20
Represents how to reach a part of a YARP network.
Definition: Contact.h:36
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,...)
Definition: LogComponent.h:154
#define yCDebug(component,...)
Definition: LogComponent.h:109
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:34
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.