YARP
Yet Another Robot Platform
TcpAcceptor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * Copyright (C) 2010 Anne van Rossum <anne@almende.com>
4  * All rights reserved.
5  *
6  * This software may be modified and distributed under the terms of the
7  * BSD-3-Clause license. See the accompanying LICENSE file for details.
8  */
9 
10 #include <yarp/conf/system.h>
11 #ifndef YARP_HAS_ACE
12 
13 // General files
14 
19 
20 using namespace yarp::os::impl;
21 using namespace yarp::os;
22 
23 #define BACKLOG 1
24 
25 namespace {
26 YARP_OS_LOG_COMPONENT(TCPACCEPTOR_POSIX, "yarp.os.impl.TcpAcceptor.posix")
27 }
28 
32 void sigchld_handler(int /*s*/)
33 {
34  while(waitpid(-1, nullptr, WNOHANG) > 0) {}
35 }
36 
37 
38 /* **************************************************************************************
39  * Implementation of TcpAcceptor
40  * **************************************************************************************/
41 
42 int TcpAcceptor::open(const Contact& address)
43 {
44  yCDebug(TCPACCEPTOR_POSIX, "TCP/IP start in server mode");
45  set_handle(socket(AF_INET, SOCK_STREAM, 0));
46  if (get_handle() < 0) {
47  yCError(TCPACCEPTOR_POSIX, "At TcpAcceptor::open there was an error: %d, %s", errno, strerror(errno));
48  return -1;
49  }
50 
51  int yes=1;
52  if (setsockopt(get_handle(), SOL_SOCKET, SO_REUSEADDR, &yes,
53  sizeof(int)) == -1) {
54  yCError(TCPACCEPTOR_POSIX, "At TcpAcceptor::open there was an error: %d, %s", errno, strerror(errno));
55  return -1;
56  }
57 
58  return shared_open(address);
59 }
60 
64 int TcpAcceptor::shared_open(const Contact& address)
65 {
66  struct sockaddr_in servAddr;
67  servAddr.sin_addr.s_addr = INADDR_ANY;
68  servAddr.sin_family = AF_INET;
69  servAddr.sin_port = htons((address.getPort()>0)?address.getPort():0);
70  inet_pton(AF_INET, address.getHost().c_str(), &servAddr.sin_addr);
71  memset(servAddr.sin_zero, '\0', sizeof servAddr.sin_zero);
72 
73  if (bind(get_handle(), (struct sockaddr *)&servAddr, sizeof (struct sockaddr)) < 0) {
74  yCError(TCPACCEPTOR_POSIX, "At bind(sockfd) there was an error: %d, %s", errno, strerror(errno));
75  return -1;
76  }
77 
78  if (listen(get_handle(), BACKLOG) < 0) {
79  yCError(TCPACCEPTOR_POSIX, "At listen(sockfd) there was an error: %d, %s", errno, strerror(errno));
80  return -1;
81  }
82 
83  struct sigaction sa;
84  sa.sa_handler = sigchld_handler;
85  sigemptyset(&sa.sa_mask);
86  sa.sa_flags = SA_RESTART;
87  if (sigaction(SIGCHLD, &sa, nullptr) < 0) {
88  yCError(TCPACCEPTOR_POSIX, "At sigaction(address) there was an error: %d, %s", errno, strerror(errno));
89  return -1;
90  }
91 
92  struct sockaddr_in sin;
93  socklen_t addrlen = sizeof(sin);
94  if (getsockname(get_handle(), (struct sockaddr *)&sin, &addrlen) == 0 &&
95  sin.sin_family == AF_INET &&
96  addrlen == sizeof(sin)) {
97  port_number = static_cast<int>(ntohs(sin.sin_port));
98  } else {
99  yCError(TCPACCEPTOR_POSIX, "At getsockname(address) there was an error: %d, %s", errno, strerror(errno));
100  return -1;
101  }
102 
103  return 1;
104 }
105 
106 
110 int TcpAcceptor::accept(TcpStream &new_stream)
111 {
112  sockaddr* addr = nullptr;
113  int len = 0;
114  int* len_ptr = &len;
115 
116  new_stream.set_handle(::accept(get_handle(), reinterpret_cast<struct sockaddr*>(&addr), reinterpret_cast<socklen_t*>(len_ptr)));
117  if (new_stream.get_handle() < 0) {
118  yCError(TCPACCEPTOR_POSIX, "At accept(sockfd) there was an error: %d, %s", errno, strerror(errno));
119  return -1;
120  }
121 
122  return 1;
123 }
124 
125 int TcpAcceptor::close()
126 {
127  int result = 0;
128 
129  if (get_handle() != -1) {
130  result = ::close(get_handle());
131  set_handle (-1);
132  }
133  return result;
134 }
135 
136 #endif
PlatformSysWait.h
LogComponent.h
yarp::os::impl::posix::TcpStream::get_handle
int get_handle()
Definition: TcpStream.h:111
yarp::os::Contact::getPort
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition: Contact.cpp:242
TcpAcceptor.h
BACKLOG
#define BACKLOG
Definition: TcpAcceptor.cpp:23
system.h
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os::impl::posix::TcpStream::set_handle
void set_handle(int h)
Definition: TcpStream.h:114
sigchld_handler
void sigchld_handler(int)
An error handler that reaps the zombies.
Definition: TcpAcceptor.cpp:32
PlatformSignal.h
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:112
yarp::os::impl::posix::TcpStream
Definition: TcpStream.h:34
yarp::os::Contact::getHost
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:231
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
YARP_OS_LOG_COMPONENT
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:37
yarp::os::impl
The components from which ports and connections are built.