Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpServer.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See https://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * TCP Server
33 *
34*****************************************************************************/
35
36#include <visp3/core/vpServer.h>
37
38#include <sstream>
39
40// inet_ntop() not supported on win XP
41#ifdef VISP_HAVE_FUNC_INET_NTOP
42
43#if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
44#include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IPHONE or TARGET_OS_IOS macro
45#endif
46
50vpServer::vpServer() : adress(), port(0), started(false), max_clients(10)
51{
52 int protocol = 0;
53 emitter.socketFileDescriptorEmitter = socket(AF_INET, SOCK_STREAM, protocol);
54#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
55 if (emitter.socketFileDescriptorEmitter < 0)
56#else
57 if (emitter.socketFileDescriptorEmitter == INVALID_SOCKET)
58#endif
59 {
60 vpERROR_TRACE("vpServer::vpServer(), cannot open socket.");
61 }
62 emitter.emitterAddress.sin_family = AF_INET;
63 emitter.emitterAddress.sin_addr.s_addr = INADDR_ANY;
64 emitter.emitterAddress.sin_port = 0;
65
66 adress = inet_ntoa(emitter.emitterAddress.sin_addr);
67 port = emitter.emitterAddress.sin_port;
68}
69
75vpServer::vpServer(const int &port_serv) : adress(), port(0), started(false), max_clients(10)
76{
77 int protocol = 0;
78 emitter.socketFileDescriptorEmitter = socket(AF_INET, SOCK_STREAM, protocol);
79#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
80 if (emitter.socketFileDescriptorEmitter < 0)
81#else
82 if (emitter.socketFileDescriptorEmitter == INVALID_SOCKET)
83#endif
84 {
85 vpERROR_TRACE("vpServer::vpServer(const int &port_serv), cannot open socket.");
86 }
87 emitter.emitterAddress.sin_family = AF_INET;
88 emitter.emitterAddress.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");;
89 emitter.emitterAddress.sin_port = htons((unsigned short)port_serv);
90
91 adress = inet_ntoa(emitter.emitterAddress.sin_addr);
92 port = port_serv;
93}
94
101vpServer::vpServer(const std::string &adress_serv, const int &port_serv)
102 : adress(), port(0), started(false), max_clients(10)
103{
104 int protocol = 0;
105 emitter.socketFileDescriptorEmitter = socket(AF_INET, SOCK_STREAM, protocol);
106#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
107 if (emitter.socketFileDescriptorEmitter < 0)
108#else
109 if (emitter.socketFileDescriptorEmitter == INVALID_SOCKET)
110#endif
111 {
112 vpERROR_TRACE("vpServer::vpServer(const std::string &adress_serv,const "
113 "int &port_serv), cannot open socket.");
114 }
115 emitter.emitterAddress.sin_family = AF_INET;
116 emitter.emitterAddress.sin_addr.s_addr = inet_addr(adress_serv.c_str());
117 emitter.emitterAddress.sin_port = htons((unsigned short)port_serv);
118
119 adress = adress_serv;
120 port = port_serv;
121}
122
127{
128#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
129 close(emitter.socketFileDescriptorEmitter);
130#else // Win32
131 closesocket((unsigned)emitter.socketFileDescriptorEmitter);
132#endif
133
134 for (unsigned int i = 0; i < receptor_list.size(); i++)
135#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
136 close(receptor_list[i].socketFileDescriptorReceptor);
137#else // Win32
138 closesocket((unsigned)receptor_list[i].socketFileDescriptorReceptor);
139#endif
140}
141
148{
149 int serverStructLength = sizeof(emitter.emitterAddress);
150#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
151 int bindResult = bind(emitter.socketFileDescriptorEmitter, (struct sockaddr *)&emitter.emitterAddress,
152 (unsigned)serverStructLength);
153#else // Win32
154 int bindResult = bind((unsigned)emitter.socketFileDescriptorEmitter, (struct sockaddr *)&emitter.emitterAddress,
155 serverStructLength);
156#endif
157
158 if (bindResult < 0) {
159 std::cout << "Error id : " << bindResult << std::endl;
160 std::stringstream errorMessage;
161 errorMessage << "vpServer::vpServer(), cannot bind to port";
162 errorMessage << " ";
163 errorMessage << port;
164 errorMessage << " The port may be already used.";
165
166 vpERROR_TRACE(errorMessage.str().c_str());
167 return false;
168 }
169
170#ifdef SO_NOSIGPIPE
171 // Mac OS X does not have the MSG_NOSIGNAL flag. It does have this
172 // connections based version, however.
173 if (emitter.socketFileDescriptorEmitter > 0) {
174 int set_option = 1;
175 if (0 ==
176 setsockopt(emitter.socketFileDescriptorEmitter, SOL_SOCKET, SO_NOSIGPIPE, &set_option, sizeof(set_option))) {
177 } else {
178 std::cout << "Failed to set socket signal option" << std::endl;
179 }
180 }
181#endif // SO_NOSIGPIPE
182
183#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
184 listen(emitter.socketFileDescriptorEmitter, (int)max_clients);
185#else // Win32
186 listen((unsigned)emitter.socketFileDescriptorEmitter, (int)max_clients);
187#endif
188
189 std::cout << "Server ready" << std::endl;
190
191 started = true;
192
193 return true;
194}
195
203{
204 if (!started)
205 if (!start()) {
206 return false;
207 }
208
209 tv.tv_sec = tv_sec;
210#ifdef TARGET_OS_IPHONE
211 tv.tv_usec = (int)tv_usec;
212#else
213 tv.tv_usec = tv_usec;
214#endif
215
216 FD_ZERO(&readFileDescriptor);
217
218 socketMax = emitter.socketFileDescriptorEmitter;
219 FD_SET((unsigned)emitter.socketFileDescriptorEmitter, &readFileDescriptor);
220
221 for (unsigned int i = 0; i < receptor_list.size(); i++) {
222 FD_SET((unsigned)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor);
223
224 if (i == 0)
225 socketMax = receptor_list[i].socketFileDescriptorReceptor;
226
227 if (socketMax < receptor_list[i].socketFileDescriptorReceptor)
228 socketMax = receptor_list[i].socketFileDescriptorReceptor;
229 }
230
231 int value = select((int)socketMax + 1, &readFileDescriptor, NULL, NULL, &tv);
232 if (value == -1) {
233 // vpERROR_TRACE( "vpServer::run(), select()" );
234 return false;
235 } else if (value == 0) {
236 return false;
237 } else {
238 if (FD_ISSET((unsigned int)emitter.socketFileDescriptorEmitter, &readFileDescriptor)) {
239 vpNetwork::vpReceptor client;
240 client.receptorAddressSize = sizeof(client.receptorAddress);
241#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
242 client.socketFileDescriptorReceptor = accept(
243 emitter.socketFileDescriptorEmitter, (struct sockaddr *)&client.receptorAddress, &client.receptorAddressSize);
244#else // Win32
245 client.socketFileDescriptorReceptor =
246 accept((unsigned int)emitter.socketFileDescriptorEmitter, (struct sockaddr *)&client.receptorAddress,
247 &client.receptorAddressSize);
248#endif
249
250#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
251 if ((client.socketFileDescriptorReceptor) == -1)
252#else
253 if ((client.socketFileDescriptorReceptor) == INVALID_SOCKET)
254#endif
255 vpERROR_TRACE("vpServer::run(), accept()");
256
257 client.receptorIP = inet_ntoa(client.receptorAddress.sin_addr);
258 printf("New client connected : %s\n", inet_ntoa(client.receptorAddress.sin_addr));
259 receptor_list.push_back(client);
260
261 return true;
262 } else {
263 for (unsigned int i = 0; i < receptor_list.size(); i++) {
264 if (FD_ISSET((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &readFileDescriptor)) {
265 char deco;
266#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
267 ssize_t numbytes = recv(receptor_list[i].socketFileDescriptorReceptor, &deco, 1, MSG_PEEK);
268#else // Win32
269 int numbytes = recv((unsigned int)receptor_list[i].socketFileDescriptorReceptor, &deco, 1, MSG_PEEK);
270#endif
271
272 if (numbytes == 0) {
273 std::cout << "Disconnected : " << inet_ntoa(receptor_list[i].receptorAddress.sin_addr) << std::endl;
274 receptor_list.erase(receptor_list.begin() + (int)i);
275 return 0;
276 }
277 }
278 }
279 }
280 }
281
282 return false;
283}
284
289
290#elif !defined(VISP_BUILD_SHARED_LIBS)
291// Work around to avoid warning: libvisp_core.a(vpServer.cpp.o) has no symbols
292void dummy_vpServer(){};
293#endif
long tv_sec
Definition vpNetwork.h:147
int socketMax
Definition vpNetwork.h:130
fd_set readFileDescriptor
Definition vpNetwork.h:128
long tv_usec
Definition vpNetwork.h:148
std::vector< vpReceptor > receptor_list
Definition vpNetwork.h:127
struct timeval tv
Definition vpNetwork.h:146
vpEmitter emitter
Definition vpNetwork.h:126
void print(const char *id="")
virtual ~vpServer()
Definition vpServer.cpp:126
bool start()
Definition vpServer.cpp:147
bool checkForConnections()
Definition vpServer.cpp:202
void print()
Definition vpServer.cpp:288
#define vpERROR_TRACE
Definition vpDebug.h:388