client_socket.cpp
Go to the documentation of this file.
1 /*
2  * @brief client_socket encapsulates connecting, closing and setting socket options
3  * for tcp client sockets using boost::asio::ip::tcp::socket and boost::asio::io_service.
4  *
5  * Copyright (C) 2019 Ing.-Buero Dr. Michael Lehning, Hildesheim
6  * Copyright (C) 2019 SICK AG, Waldkirch
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions are met:
24  *
25  * * Redistributions of source code must retain the above copyright
26  * notice, this list of conditions and the following disclaimer.
27  * * Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * * Neither the name of SICK AG nor the names of its
31  * contributors may be used to endorse or promote products derived from
32  * this software without specific prior written permission
33  * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
41  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47  * POSSIBILITY OF SUCH DAMAGE.
48  *
49  * Authors:
50  * Michael Lehning <michael.lehning@lehning.de>
51  *
52  * Copyright 2019 SICK AG
53  * Copyright 2019 Ing.-Buero Dr. Michael Lehning
54  *
55  */
56 #include "sick_scan/ros_wrapper.h"
57 
59 
64 sick_scan::ClientSocket::ClientSocket(boost::asio::io_service & io_service) : m_tcp_socket(io_service)
65 {
66 }
67 
72 {
73  close();
74 }
75 
83 bool sick_scan::ClientSocket::connect(boost::asio::io_service & io_service, const std::string & server_adress, int tcp_port)
84 {
85  try
86  {
87  // Connect to server
88  boost::asio::ip::tcp::resolver tcpresolver(io_service);
89  boost::asio::ip::tcp::resolver::query tcpquery(server_adress, std::to_string(tcp_port));
90  boost::asio::ip::tcp::resolver::iterator it = tcpresolver.resolve(tcpquery);
91  boost::system::error_code errorcode;
92  m_tcp_socket.connect(*it, errorcode);
93 
94  if(!errorcode && m_tcp_socket.is_open())
95  {
96  // Get and set options for client sockets
97  boost::system::error_code socket_option_errorcodes[3];
98  boost::asio::ip::tcp::no_delay socket_option_no_delay;
99  boost::asio::socket_base::send_buffer_size socket_option_send_buffer_size;
100  boost::asio::socket_base::receive_buffer_size socket_option_receive_buffer_size;
101 
102  m_tcp_socket.get_option(socket_option_no_delay, socket_option_errorcodes[0]);
103  m_tcp_socket.get_option(socket_option_send_buffer_size, socket_option_errorcodes[1]);
104  m_tcp_socket.get_option(socket_option_receive_buffer_size, socket_option_errorcodes[2]);
105 
106  if (socket_option_errorcodes[0] || socket_option_no_delay.value() == false)
107  m_tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true), socket_option_errorcodes[0]);
108  if (socket_option_errorcodes[1] || socket_option_send_buffer_size.value() < 64 * 1024)
109  m_tcp_socket.set_option(boost::asio::socket_base::send_buffer_size(64 * 1024), socket_option_errorcodes[1]);
110  if (socket_option_errorcodes[2] || socket_option_receive_buffer_size.value() < 64 * 1024)
111  m_tcp_socket.set_option(boost::asio::socket_base::receive_buffer_size(64 * 1024), socket_option_errorcodes[2]);
112 
113  m_tcp_socket.get_option(socket_option_no_delay, socket_option_errorcodes[0]);
114  m_tcp_socket.get_option(socket_option_send_buffer_size, socket_option_errorcodes[1]);
115  m_tcp_socket.get_option(socket_option_receive_buffer_size, socket_option_errorcodes[2]);
116 
117  if(socket_option_errorcodes[0] || socket_option_errorcodes[1] || socket_option_errorcodes[2])
118  {
119  ROS_WARN_STREAM("## ClientSocket::connect(): socket connected to " << server_adress << ":" << tcp_port << ", but socket::get_option() failed, "
120  << " socket options error messages: no_delay=" << socket_option_errorcodes[0].message() << ", send_buffer_size=" << socket_option_errorcodes[1].message()
121  << ", receive_buffer_size=" << socket_option_errorcodes[2].message());
122  }
123  ROS_INFO_STREAM("ClientSocket::connect(): socket connected to " << server_adress << ":" << tcp_port << ", socket options values: no_delay=" << socket_option_no_delay.value()
124  << ", send_buffer_size=" << socket_option_send_buffer_size.value() << ", receive_buffer_size=" << socket_option_receive_buffer_size.value());
125  }
126  else
127  {
128  ROS_WARN_STREAM("ClientSocket::connect(): no connection to localization controller " << server_adress << ":" << tcp_port << ", error " << errorcode.value() << " \"" << errorcode.message() << "\"");
129  return false;
130  }
131  return true;
132  }
133  catch(std::exception & exc)
134  {
135  ROS_WARN_STREAM("## ERROR ClientSocket::connect(): connect to " << server_adress << ":" << tcp_port << " failed, exception " << exc.what());
136  }
137  return false;
138 }
139 
146 bool sick_scan::ClientSocket::close(bool force_shutdown)
147 {
148  try
149  {
150  if (force_shutdown || m_tcp_socket.is_open())
151  {
152  m_tcp_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
153  m_tcp_socket.close();
154  }
155  return true;
156  }
157  catch(std::exception & exc)
158  {
159  ROS_WARN_STREAM("ColaTransmitter::closeTcpConnections(): exception " << exc.what() << " on closing connection.");
160  }
161  return false;
162 }
163 
boost::asio::ip::tcp::socket m_tcp_socket
tcp client socket implementation
#define ROS_WARN_STREAM(args)
ClientSocket(boost::asio::io_service &io_service)
#define ROS_INFO_STREAM(args)
virtual bool close(bool force_shutdown=false)
virtual bool connect(boost::asio::io_service &io_service, const std::string &server_adress, int tcp_port)


sick_scan
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Wed Sep 7 2022 02:25:06