@@ -163,7 +163,6 @@ void Client::set_tcp_timeout(std::size_t tcp_timeout) {
163163}
164164#endif
165165
166-
167166Client::~Client () {
168167 if (modbus != nullptr ) {
169168 modbus_close (modbus);
@@ -180,6 +179,47 @@ void Client::set_debug(bool debug) {
180179 }
181180}
182181
182+ /* *
183+ * @brief convert socket address to string
184+ * @param sa socket address
185+ * @return sa as string
186+ */
187+ static std::string sockaddr_to_str (const sockaddr_storage &sa) {
188+ char buffer[INET6_ADDRSTRLEN + 1 ];
189+ if (sa.ss_family == AF_INET) {
190+ auto peer_in = reinterpret_cast <const struct sockaddr_in *>(&sa);
191+ inet_ntop (sa.ss_family , &peer_in->sin_addr , buffer, sizeof (buffer));
192+ std::ostringstream sstr;
193+ return buffer;
194+ } else if (sa.ss_family == AF_INET6) {
195+ auto peer_in6 = reinterpret_cast <const struct sockaddr_in6 *>(&sa);
196+ inet_ntop (sa.ss_family , &peer_in6->sin6_addr , buffer, sizeof (buffer));
197+ std::ostringstream sstr;
198+ sstr << ' [' << buffer << ' ]' ;
199+ return sstr.str ();
200+ } else {
201+ return " UNKNOWN" ;
202+ }
203+ }
204+
205+ std::string Client::get_listen_addr () {
206+ struct sockaddr_storage sock_addr;
207+ socklen_t len = sizeof (sock_addr);
208+ int tmp = getsockname (socket, reinterpret_cast <struct sockaddr *>(&sock_addr), &len);
209+
210+ if (tmp < 0 ) {
211+ const std::string error_msg = modbus_strerror (errno);
212+ throw std::runtime_error (" getsockname failed: " + error_msg);
213+ }
214+
215+ std::ostringstream sstr;
216+ sstr << sockaddr_to_str (sock_addr);
217+ // the port entries have the same offset and size in sockaddr_in and sockaddr_in6
218+ sstr << ' :' << htons (reinterpret_cast <const struct sockaddr_in *>(&sock_addr)->sin_port );
219+
220+ return sstr.str ();
221+ }
222+
183223std::string Client::connect_client () {
184224 int tmp = modbus_tcp_pi_accept (modbus, &socket);
185225 if (tmp < 0 ) {
@@ -198,18 +238,9 @@ std::string Client::connect_client() {
198238
199239 std::ostringstream sstr;
200240
201- char buffer[INET6_ADDRSTRLEN + 1 ];
202- if (peer_addr.ss_family == AF_INET) {
203- auto peer_in = reinterpret_cast <const struct sockaddr_in *>(&peer_addr);
204- inet_ntop (peer_addr.ss_family , &peer_in->sin_addr , buffer, sizeof (buffer));
205- sstr << buffer << ' :' << htons (peer_in->sin_port );
206- } else if (peer_addr.ss_family == AF_INET6) {
207- auto peer_in6 = reinterpret_cast <const struct sockaddr_in6 *>(&peer_addr);
208- inet_ntop (peer_addr.ss_family , &peer_in6->sin6_addr , buffer, sizeof (buffer));
209- sstr << buffer << ' :' << htons (peer_in6->sin6_port );
210- } else {
211- sstr << " UNKNOWN" << ' :' << peer_addr.ss_family ;
212- }
241+ sstr << sockaddr_to_str (peer_addr);
242+ // the port entries have the same offset and size in sockaddr_in and sockaddr_in6
243+ sstr << ' :' << htons (reinterpret_cast <const struct sockaddr_in *>(&peer_addr)->sin_port );
213244
214245 return sstr.str ();
215246}
0 commit comments