Main MRPT website > C++ reference for MRPT 1.9.9
CServerTCPSocket_common.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "comms-precomp.h" // Precompiled headers
11 
14 #include <mrpt/comms/net_utils.h>
15 #include <mrpt/system/os.h>
16 #include <cstdio> // stderr
17 using namespace mrpt::comms;
18 
19 #if defined(MRPT_OS_LINUX) || defined(MRPT_OS_APPLE)
20 #define INVALID_SOCKET (-1)
21 
22 #include <sys/socket.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/ioctl.h>
28 #include <netdb.h>
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
31 #endif
32 
33 #ifdef MRPT_OS_WINDOWS
34 #include <winsock.h>
35 typedef int socklen_t;
36 #endif
37 
39 {
41 }
42 
44  unsigned short listenPort, const std::string& IPaddress,
45  int maxConnectionsWaiting)
46 {
48 
49  // Create the socket:
50  // ----------------------------
51  m_serverSock = socket(AF_INET, SOCK_STREAM, 0);
53 
54  // Bind it:
55  // ----------------------------
56  sockaddr_in desiredIP;
57 
58  desiredIP.sin_family = AF_INET;
59  desiredIP.sin_addr.s_addr = inet_addr(IPaddress.c_str());
60  desiredIP.sin_port = htons((unsigned short)listenPort);
61 
62  if (INVALID_SOCKET ==
63  ::bind(m_serverSock, (struct sockaddr*)(&desiredIP), sizeof(desiredIP)))
65 
66  // Put in listen mode:
67  // ----------------------------
68  if (INVALID_SOCKET == listen(m_serverSock, maxConnectionsWaiting))
70 
72  format(
73  "[CServerTCPSocket] Listening at %s:%i\n", IPaddress.c_str(),
74  listenPort));
75 
76  MRPT_END
77 }
78 
79 /*---------------------------------------------------------------
80  isListening
81  ---------------------------------------------------------------*/
83 /*---------------------------------------------------------------
84  accept
85  ---------------------------------------------------------------*/
86 std::unique_ptr<CClientTCPSocket> CServerTCPSocket::accept(int timeout_ms)
87 {
89 
90  if (m_serverSock == INVALID_SOCKET) return nullptr;
91 
92  struct timeval timeoutSelect;
93  struct timeval* ptrTimeout;
94  fd_set sockArr;
95 
96  // Init fd_set structure & add our socket to it:
97  FD_ZERO(&sockArr);
98  FD_SET(m_serverSock, &sockArr);
99 
100  // The timeout:
101  if (timeout_ms < 0)
102  {
103  ptrTimeout = nullptr;
104  }
105  else
106  {
107  timeoutSelect.tv_sec = timeout_ms / 1000;
108  timeoutSelect.tv_usec = 1000 * (timeout_ms % 1000);
109  ptrTimeout = &timeoutSelect;
110  }
111 
112  // Wait for READ flag (meaning incoming connections):
113  MRPT_LOG_DEBUG("[CServerTCPSocket::accept] Waiting incoming connections");
114 
115  int selRet = ::select(
116  m_serverSock + 1, // __nfds
117  &sockArr, // Wait for read
118  nullptr, // Wait for write
119  nullptr, // Wait for except.
120  ptrTimeout); // Timeout
121 
122  if (selRet == INVALID_SOCKET)
123  {
124  fprintf(stderr, "%s\n", getLastErrorStr().c_str());
125  return nullptr;
126  }
127 
128  if (selRet == 0)
129  {
131  "[CServerTCPSocket::accept] Timeout waiting incoming "
132  "connections\n");
133 
134  // Timeout:
135  return nullptr;
136  }
137  else
138  {
140  "[CServerTCPSocket::accept] Incoming connection accepted\n");
141 
142  // We have a new connection:
143 
144  sockaddr_in otherPart;
145  socklen_t otherPartSize = sizeof(otherPart);
146 
147  int aceptdSock = ::accept(
148  m_serverSock, (struct sockaddr*)&otherPart, &otherPartSize);
149 
150  if (aceptdSock == INVALID_SOCKET)
151  {
152  MRPT_LOG_ERROR_FMT("%s\n", getLastErrorStr().c_str());
153  return std::unique_ptr<CClientTCPSocket>();
154  }
155 
156  auto ret = std::make_unique<CClientTCPSocket>();
157 
158  ret->m_hSock = aceptdSock;
159 
160  ret->m_remotePartIP = std::string(inet_ntoa(otherPart.sin_addr));
161  ret->m_remotePartPort = ntohs(otherPart.sin_port);
162 
164  "[CServerTCPSocket::accept] Connection accepted from %s:%u\n",
165  ret->m_remotePartIP.c_str(), ret->m_remotePartPort);
166 
167  return ret;
168  }
169 
170  MRPT_END
171 }
#define INVALID_SOCKET
#define THROW_EXCEPTION(msg)
#define MRPT_LOG_DEBUG_FMT(_FMT_STRING,...)
std::string getLastSocketErrorStr()
Returns a description of the last Sockets error.
Definition: net_utils.cpp:475
std::string getLastErrorStr()
Returns a description of the last Sockets error.
#define MRPT_LOG_ERROR_FMT(_FMT_STRING,...)
std::unique_ptr< CClientTCPSocket > accept(int timeout_ms=-1)
Waits for an incoming connection (indefinitely, or with a given timeout) The returned object represen...
void setupSocket(unsigned short listenPort, const std::string &IPaddress, int maxConnectionsWaiting)
Common code called from the platform-dependant constructor.
#define MRPT_END
#define MRPT_LOG_WARN(_STRING)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
#define MRPT_LOG_DEBUG(_STRING)
GLsizei const GLchar ** string
Definition: glext.h:4101
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:405
#define MRPT_START
int m_serverSock
The handle for the listening server TCP socket.
bool isListening()
Returns true if the socket was successfully open and it&#39;s bound to the desired port.
Serial and networking devices and utilities.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019