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
17using namespace yarp::os::impl;
18using namespace yarp::os;
19
20#define BACKLOG 1
21
22namespace {
23YARP_OS_LOG_COMPONENT(TCPACCEPTOR_POSIX, "yarp.os.impl.TcpAcceptor.posix")
24}
25
29void sigchld_handler(int /*s*/)
30{
31 while(waitpid(-1, nullptr, WNOHANG) > 0) {}
32}
33
34
35/* **************************************************************************************
36 * Implementation of TcpAcceptor
37 * **************************************************************************************/
38
39int 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
61int 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
107int 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
122int 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: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,...)
Definition: LogComponent.h:213
#define yCDebug(component,...)
Definition: LogComponent.h:128
#define YARP_OS_LOG_COMPONENT(name, name_string)
Definition: LogComponent.h:29
The components from which ports and connections are built.
An interface to the operating system, including Port based communication.