Visual Servoing Platform version 3.5.0
vpClient.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 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 http://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 Client
33 *
34 * Authors:
35 * Aurelien Yol
36 *
37 *****************************************************************************/
38
39#include <visp3/core/vpClient.h>
40
41// inet_ntop() not supported on win XP
42#ifdef VISP_HAVE_FUNC_INET_NTOP
43
44vpClient::vpClient() : vpNetwork(), numberOfAttempts(0) {}
45
50
62bool vpClient::connectToHostname(const std::string &hostname, const unsigned int &port_serv)
63{
64 // get server host information from hostname
65 struct hostent *server = gethostbyname(hostname.c_str());
66
67 if (server == NULL) {
68 std::string noSuchHostMessage("ERROR, ");
69 noSuchHostMessage.append(hostname);
70 noSuchHostMessage.append(": no such host\n");
71 vpERROR_TRACE(noSuchHostMessage.c_str(), "vpClient::connectToHostname("
72 "const std::string &hostname, "
73 "const int &port_serv)");
74 return false;
75 }
76
77 vpNetwork::vpReceptor serv;
78
79 serv.socketFileDescriptorReceptor = socket(AF_INET, SOCK_STREAM, 0);
80
81#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
82 if (serv.socketFileDescriptorReceptor < 0) {
83#else
84 if (serv.socketFileDescriptorReceptor == INVALID_SOCKET) {
85#endif
86 vpERROR_TRACE("ERROR opening socket", "vpClient::connectToHostname()");
87 return false;
88 }
89
90 memset((char *)&serv.receptorAddress, '\0', sizeof(serv.receptorAddress));
91 serv.receptorAddress.sin_family = AF_INET;
92 memmove((char *)&serv.receptorAddress.sin_addr.s_addr, (char *)server->h_addr, (unsigned)server->h_length);
93 serv.receptorAddress.sin_port = htons((unsigned short)port_serv);
94 serv.receptorIP = inet_ntoa(*(in_addr *)server->h_addr);
95
96 return connectServer(serv);
97}
98
109bool vpClient::connectToIP(const std::string &ip, const unsigned int &port_serv)
110{
111 vpNetwork::vpReceptor serv;
112
113 serv.socketFileDescriptorReceptor = socket(AF_INET, SOCK_STREAM, 0);
114
115#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
116 if (serv.socketFileDescriptorReceptor < 0) {
117#else
118 if (serv.socketFileDescriptorReceptor == INVALID_SOCKET) {
119#endif
120 vpERROR_TRACE("ERROR opening socket", "vpClient::connectToIP()");
121 return false;
122 }
123
124 memset((char *)&serv.receptorAddress, '\0', sizeof(serv.receptorAddress));
125 serv.receptorAddress.sin_family = AF_INET;
126 serv.receptorAddress.sin_addr.s_addr = inet_addr(ip.c_str());
127 serv.receptorAddress.sin_port = htons((unsigned short)port_serv);
128
129 return connectServer(serv);
130}
131
137void vpClient::deconnect(const unsigned int &index)
138{
139 if (index < receptor_list.size()) {
140#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
141 shutdown(receptor_list[index].socketFileDescriptorReceptor, SHUT_RDWR);
142#else // _WIN32
143 shutdown(receptor_list[index].socketFileDescriptorReceptor, SD_BOTH);
144#endif
145 receptor_list.erase(receptor_list.begin() + (int)index);
146 }
147}
148
153{
154 for (unsigned int i = 0; i < receptor_list.size(); i++) {
155#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
156 shutdown(receptor_list[i].socketFileDescriptorReceptor, SHUT_RDWR);
157#else // _WIN32
158 shutdown(receptor_list[i].socketFileDescriptorReceptor, SD_BOTH);
159#endif
160 receptor_list.erase(receptor_list.begin() + (int)i);
161 i--;
162 }
163}
164
169
170// Private function
171bool vpClient::connectServer(vpNetwork::vpReceptor &serv)
172{
173 serv.receptorAddressSize = sizeof(serv.receptorAddress);
174
175 numberOfAttempts = 15;
176 unsigned int ind = 1;
177 int connectionResult = -1;
178
179 while (ind <= numberOfAttempts) {
180 std::cout << "Attempt number " << ind << "..." << std::endl;
181
182 connectionResult =
183 connect(serv.socketFileDescriptorReceptor, (sockaddr *)&serv.receptorAddress, serv.receptorAddressSize);
184 if (connectionResult >= 0)
185 break;
186
187 ind++;
188 vpTime::wait(1000);
189 }
190
191 if (connectionResult < 0) {
192 vpERROR_TRACE("ERROR connecting, the server may not be waiting for "
193 "connection at this port.",
194 "vpClient::connectServer()");
195
196 return false;
197 }
198
199 receptor_list.push_back(serv);
200
201#ifdef SO_NOSIGPIPE
202 // Mac OS X does not have the MSG_NOSIGNAL flag. It does have this
203 // connections based version, however.
204 if (serv.socketFileDescriptorReceptor > 0) {
205 int set_option = 1;
206 if (0 == setsockopt(serv.socketFileDescriptorReceptor, SOL_SOCKET, SO_NOSIGPIPE, &set_option, sizeof(set_option))) {
207 } else {
208 std::cout << "Failed to set socket signal option" << std::endl;
209 }
210 }
211#endif // SO_NOSIGPIPE
212
213 std::cout << "Connected!" << std::endl;
214 return true;
215}
216
217#elif !defined(VISP_BUILD_SHARED_LIBS)
218// Work arround to avoid warning: libvisp_core.a(vpClient.cpp.o) has no symbols
219void dummy_vpClient(){};
220#endif
void print()
Definition: vpClient.cpp:168
virtual ~vpClient()
Definition: vpClient.cpp:49
bool connectToIP(const std::string &ip, const unsigned int &port_serv)
Definition: vpClient.cpp:109
bool connectToHostname(const std::string &hostname, const unsigned int &port_serv)
Definition: vpClient.cpp:62
vpClient()
Definition: vpClient.cpp:44
void deconnect(const unsigned int &index=0)
Definition: vpClient.cpp:137
void stop()
Definition: vpClient.cpp:152
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:91
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:130
void print(const char *id="")
Definition: vpNetwork.cpp:123
#define vpERROR_TRACE
Definition: vpDebug.h:393
VISP_EXPORT int wait(double t0, double t)