Visual Servoing Platform  version 3.1.0
vpClient.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 vpClient::vpClient() : vpNetwork(), numberOfAttempts(0) {}
42 
47 
59 bool vpClient::connectToHostname(const std::string &hostname, const unsigned int &port_serv)
60 {
61  // get server host information from hostname
62  struct hostent *server = gethostbyname(hostname.c_str());
63 
64  if (server == NULL) {
65  std::string noSuchHostMessage("ERROR, ");
66  noSuchHostMessage.append(hostname);
67  noSuchHostMessage.append(": no such host\n");
68  vpERROR_TRACE(noSuchHostMessage.c_str(), "vpClient::connectToHostname("
69  "const std::string &hostname, "
70  "const int &port_serv)");
71  return false;
72  }
73 
74  vpNetwork::vpReceptor serv;
75 
76  serv.socketFileDescriptorReceptor = socket(AF_INET, SOCK_STREAM, 0);
77 
78 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
79  if (serv.socketFileDescriptorReceptor < 0) {
80 #else
81  if (serv.socketFileDescriptorReceptor == INVALID_SOCKET) {
82 #endif
83  vpERROR_TRACE("ERROR opening socket", "vpClient::connectToHostname()");
84  return false;
85  }
86 
87  memset((char *)&serv.receptorAddress, '\0', sizeof(serv.receptorAddress));
88  serv.receptorAddress.sin_family = AF_INET;
89  memmove((char *)&serv.receptorAddress.sin_addr.s_addr, (char *)server->h_addr, (unsigned)server->h_length);
90  serv.receptorAddress.sin_port = htons((unsigned short)port_serv);
91  serv.receptorIP = inet_ntoa(*(in_addr *)server->h_addr);
92 
93  return connectServer(serv);
94 }
95 
106 bool vpClient::connectToIP(const std::string &ip, const unsigned int &port_serv)
107 {
108  vpNetwork::vpReceptor serv;
109 
110  serv.socketFileDescriptorReceptor = socket(AF_INET, SOCK_STREAM, 0);
111 
112 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
113  if (serv.socketFileDescriptorReceptor < 0) {
114 #else
115  if (serv.socketFileDescriptorReceptor == INVALID_SOCKET) {
116 #endif
117  vpERROR_TRACE("ERROR opening socket", "vpClient::connectToIP()");
118  return false;
119  }
120 
121  memset((char *)&serv.receptorAddress, '\0', sizeof(serv.receptorAddress));
122  serv.receptorAddress.sin_family = AF_INET;
123  serv.receptorAddress.sin_addr.s_addr = inet_addr(ip.c_str());
124  serv.receptorAddress.sin_port = htons((unsigned short)port_serv);
125 
126  return connectServer(serv);
127 }
128 
134 void vpClient::deconnect(const unsigned int &index)
135 {
136  if (index < receptor_list.size()) {
137 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
138  shutdown(receptor_list[index].socketFileDescriptorReceptor, SHUT_RDWR);
139 #else // _WIN32
140  shutdown(receptor_list[index].socketFileDescriptorReceptor, SD_BOTH);
141 #endif
142  receptor_list.erase(receptor_list.begin() + (int)index);
143  }
144 }
145 
150 {
151  for (unsigned int i = 0; i < receptor_list.size(); i++) {
152 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
153  shutdown(receptor_list[i].socketFileDescriptorReceptor, SHUT_RDWR);
154 #else // _WIN32
155  shutdown(receptor_list[i].socketFileDescriptorReceptor, SD_BOTH);
156 #endif
157  receptor_list.erase(receptor_list.begin() + (int)i);
158  i--;
159  }
160 }
161 
165 void vpClient::print() { vpNetwork::print("Server"); }
166 
167 // Private function
168 bool vpClient::connectServer(vpNetwork::vpReceptor &serv)
169 {
170  serv.receptorAddressSize = sizeof(serv.receptorAddress);
171 
172  numberOfAttempts = 15;
173  unsigned int ind = 1;
174  int connectionResult = -1;
175 
176  while (ind <= numberOfAttempts) {
177  std::cout << "Attempt number " << ind << "..." << std::endl;
178 
179  connectionResult =
180  connect(serv.socketFileDescriptorReceptor, (sockaddr *)&serv.receptorAddress, serv.receptorAddressSize);
181  if (connectionResult >= 0)
182  break;
183 
184  ind++;
185  vpTime::wait(1000);
186  }
187 
188  if (connectionResult < 0) {
189  vpERROR_TRACE("ERROR connecting, the server may not be waiting for "
190  "connection at this port.",
191  "vpClient::connectServer()");
192 
193  return false;
194  }
195 
196  receptor_list.push_back(serv);
197 
198 #ifdef SO_NOSIGPIPE
199  // Mac OS X does not have the MSG_NOSIGNAL flag. It does have this
200  // connections based version, however.
201  if (serv.socketFileDescriptorReceptor > 0) {
202  int set_option = 1;
203  if (0 == setsockopt(serv.socketFileDescriptorReceptor, SOL_SOCKET, SO_NOSIGPIPE, &set_option, sizeof(set_option))) {
204  } else {
205  std::cout << "Failed to set socket signal option" << std::endl;
206  }
207  }
208 #endif // SO_NOSIGPIPE
209 
210  std::cout << "Connected!" << std::endl;
211  return true;
212 }
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:150
void print(const char *id="")
Definition: vpNetwork.cpp:120
virtual ~vpClient()
Definition: vpClient.cpp:46
#define vpERROR_TRACE
Definition: vpDebug.h:393
bool connectToIP(const std::string &ip, const unsigned int &port_serv)
Definition: vpClient.cpp:106
void stop()
Definition: vpClient.cpp:149
void deconnect(const unsigned int &index=0)
Definition: vpClient.cpp:134
This class represents a Transmission Control Protocol (TCP) network.
Definition: vpNetwork.h:84
bool connectToHostname(const std::string &hostname, const unsigned int &port_serv)
Definition: vpClient.cpp:59
vpClient()
Definition: vpClient.cpp:41
std::vector< vpReceptor > receptor_list
Definition: vpNetwork.h:124
void print()
Definition: vpClient.cpp:165