From 8d02e474b86fabc94a3003221a8c74df5183e9fa Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Wed, 9 Nov 2011 14:07:18 +0100 Subject: [PATCH] Socket has been moved up from TcpClient --- include/Socket.hpp | 40 ++++++++++ include/TcpClient.hpp | 18 +---- src/Socket.cpp | 162 +++++++++++++++++++++++++++++++++++++++++ src/TcpClient.cpp | 166 +++--------------------------------------- 4 files changed, 216 insertions(+), 170 deletions(-) create mode 100644 include/Socket.hpp create mode 100644 src/Socket.cpp diff --git a/include/Socket.hpp b/include/Socket.hpp new file mode 100644 index 0000000..55efc5a --- /dev/null +++ b/include/Socket.hpp @@ -0,0 +1,40 @@ +#ifndef SOCKET_HPP +#define SOCKET_HPP + +#include +#include +#include + +#include + +class Socket +{ +public: + + Socket(const int domain, + const int type, + const int protocol = 0); + virtual ~Socket(); + + bool openSocket(); + void closeSocket(); + + bool connectToHost(const std::string host, + const std::string port); + bool getHostInfo(const std::string host, + const std::string port, + struct addrinfo **servinfo) const; + void printHostDetails(struct addrinfo *servinfo) const; + bool connectToFirstAddress(struct addrinfo *servinfo) const; + +protected: + + int m_socket; + + int m_domain; + int m_type; + int m_protocol; + +}; + +#endif // SOCKET_HPP diff --git a/include/TcpClient.hpp b/include/TcpClient.hpp index e0422c4..f697d9e 100644 --- a/include/TcpClient.hpp +++ b/include/TcpClient.hpp @@ -1,16 +1,13 @@ #ifndef TCP_CLIENT_HPP #define TCP_CLIENT_HPP +#include "Socket.hpp" #include "Thread.hpp" #include -#include -#include -#include - -class TcpClient +class TcpClient : public Socket { public: @@ -21,7 +18,7 @@ public: virtual ~TcpClient(); bool connect(); - bool disconnect(); + void disconnect(); bool send(const std::string msg); @@ -43,15 +40,6 @@ private: TcpClient &m_tcpClient; }; - bool openSocket(); - bool closeSocket(); - - bool connectToHost(); - bool getHostInfo(struct addrinfo **servinfo) const; - void printHostDetails(struct addrinfo *servinfo) const; - bool connectToFirstAddress(struct addrinfo *servinfo) const; - - int m_socket; std::string m_host; std::string m_port; bool m_connected; diff --git a/src/Socket.cpp b/src/Socket.cpp new file mode 100644 index 0000000..e0406fb --- /dev/null +++ b/src/Socket.cpp @@ -0,0 +1,162 @@ +#include "Socket.hpp" + +#include "Logger.hpp" +#include "Common.hpp" + +#include +#include +#include // inet_ntop + +Socket::Socket(const int domain, + const int type, + const int protocol) + : m_socket(-1) + , m_domain(domain) + , m_type(type) + , m_protocol(protocol) +{ + TRACE; + +} + + +Socket::~Socket() +{ + TRACE; +} + + +bool Socket::openSocket() +{ + TRACE; + + m_socket = socket(m_domain, m_type, m_protocol); + if ( m_socket == -1 ) { + LOG( Logger::ERR, errnoToString("ERROR opening socket. ").c_str() ); + return false; + } + + return true; +} + + +void Socket::closeSocket() +{ + TRACE; + + /// @note are the return values of shutdown and close meaningful? + shutdown(m_socket, SHUT_RDWR); + close(m_socket); + m_socket = -1; +} + + +bool Socket::connectToHost(const std::string host, + const std::string port ) +{ + TRACE; + + struct addrinfo *results(0); + if ( !getHostInfo(host, port, &results) ) + return false; + + printHostDetails(results); + + if ( !connectToFirstAddress(results) ) + return false; + + freeaddrinfo(results); + return true; +} + + +bool Socket::getHostInfo( const std::string host, + const std::string port, + struct addrinfo **servinfo) const +{ + TRACE; + + struct addrinfo hints; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 + hints.ai_socktype = SOCK_DGRAM; // Datagram socket + hints.ai_flags = AI_PASSIVE; // For wildcard IP address + hints.ai_protocol = 0; // Any protocol + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + + struct addrinfo *results; + int status = getaddrinfo(host.c_str(), port.c_str(), &hints, &results); + + if (status != 0) { + LOG( Logger::ERR, std::string("Error at network address translation: "). + append(gai_strerror(status)).c_str() ) ; + return false; + } + + *servinfo = results; + return true; +} + + +void Socket::printHostDetails(struct addrinfo *servinfo) const +{ + TRACE; + + int counter(0); + for ( struct addrinfo *it = servinfo; it != 0; it = it->ai_next) { + + counter++; + void *addr; + std::string ipver; + + if ( it->ai_family == AF_INET) { // IPv4 + struct sockaddr_in *ipv4 = (struct sockaddr_in *)it->ai_addr; + addr = &(ipv4->sin_addr); + ipver = "IPv4"; + } else { // IPv6 + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)it->ai_addr; + addr = &(ipv6->sin6_addr); + ipver = "IPv6"; + } + char ipstr[INET6_ADDRSTRLEN]; + inet_ntop( it->ai_family, addr, ipstr, sizeof ipstr ); + + LOG( Logger::DEBUG, std::string(TToStr(counter)).append(". address is "). + append(ipver).append(": "). + append(ipstr).c_str() ); + } +} + + +bool Socket::connectToFirstAddress(struct addrinfo *servinfo) const +{ + TRACE; + + for ( struct addrinfo *it = servinfo; it != 0; it = it->ai_next) + if (::connect(m_socket, it->ai_addr, it->ai_addrlen) != -1) { + char hostBuffer[256]; + char serviceBuffer[256]; + int status = getnameinfo( it->ai_addr, it->ai_addrlen, + hostBuffer, sizeof(hostBuffer), + serviceBuffer, sizeof(serviceBuffer), + NI_NAMEREQD ); + + if ( status != 0 ) { + LOG( Logger::WARNING, std::string("Could not resolve hostname. "). + append(gai_strerror(status)).c_str() ); + } else { + LOG( Logger::DEBUG, std::string("Connected to "). + append(hostBuffer).append(":"). + append(serviceBuffer).c_str() ); + } + return true; + } + + LOG( Logger::ERR, std::string("Could not connect to host," + " connection refused.").c_str() ); + return false; +} \ No newline at end of file diff --git a/src/TcpClient.cpp b/src/TcpClient.cpp index 645e3f0..14138c9 100644 --- a/src/TcpClient.cpp +++ b/src/TcpClient.cpp @@ -12,15 +12,13 @@ TcpClient::TcpClient( const std::string host, const std::string port ) - : m_socket(-1) + : Socket(AF_INET, SOCK_STREAM) , m_host(host) , m_port(port) , m_connected(false) , m_watcher(*this) { TRACE; - - m_watcher.start(); } TcpClient::~TcpClient() @@ -29,8 +27,7 @@ TcpClient::~TcpClient() disconnect(); - m_watcher.stop(); - m_watcher.join(); + } @@ -41,22 +38,25 @@ bool TcpClient::connect() if ( !openSocket() ) return false; - if ( !connectToHost() ) + if ( !connectToHost(m_host, m_port) ) return false; m_connected = true; + + m_watcher.start(); return true; } -bool TcpClient::disconnect() +void TcpClient::disconnect() { TRACE; - if ( !closeSocket() ) - return false; + closeSocket(); + m_connected = false; - return true; + m_watcher.stop(); + m_watcher.join(); } @@ -74,150 +74,6 @@ bool TcpClient::send(const std::string msg) } -bool TcpClient::openSocket() -{ - TRACE; - - m_socket = socket(AF_INET, SOCK_STREAM, 0); - if ( m_socket == -1 ) { - LOG( Logger::ERR, errnoToString("ERROR opening socket. ").c_str() ); - return false; - } - - return true; -} - - -bool TcpClient::closeSocket() -{ - TRACE; - - /// @note are the return values of shutdown and close meaningful? - // if ( shutdown(m_socket, SHUT_RDWR) == -1 ) { - // LOG( Logger::ERR, errnoToString("ERROR shuting down socket. ").c_str() ); - // return false; - // } - // - // if ( close(m_socket) == -1 ) { - // LOG( Logger::ERR, errnoToString("ERROR closing socket. ").c_str() ); - // return false; - // } - - shutdown(m_socket, SHUT_RDWR); - close(m_socket); - m_socket = -1; - - return true; -} - -bool TcpClient::connectToHost() -{ - TRACE; - - struct addrinfo *results(0); - if ( !getHostInfo(&results) ) - return false; - - printHostDetails(results); - - if ( !connectToFirstAddress(results) ) - return false; - - freeaddrinfo(results); - return true; -} - - -bool TcpClient::getHostInfo(struct addrinfo **servinfo) const -{ - TRACE; - - struct addrinfo hints; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 - hints.ai_socktype = SOCK_DGRAM; // Datagram socket - hints.ai_flags = AI_PASSIVE; // For wildcard IP address - hints.ai_protocol = 0; // Any protocol - hints.ai_canonname = NULL; - hints.ai_addr = NULL; - hints.ai_next = NULL; - - - struct addrinfo *results; - int status = getaddrinfo(m_host.c_str(), m_port.c_str(), &hints, &results); - - if (status != 0) { - LOG( Logger::ERR, std::string("Error at network address translation: "). - append(gai_strerror(status)).c_str() ) ; - return false; - } - - *servinfo = results; - return true; -} - - -void TcpClient::printHostDetails(struct addrinfo *servinfo) const -{ - TRACE; - - int counter(0); - for ( struct addrinfo *it = servinfo; it != 0; it = it->ai_next) { - - counter++; - void *addr; - std::string ipver; - - if ( it->ai_family == AF_INET) { // IPv4 - struct sockaddr_in *ipv4 = (struct sockaddr_in *)it->ai_addr; - addr = &(ipv4->sin_addr); - ipver = "IPv4"; - } else { // IPv6 - struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)it->ai_addr; - addr = &(ipv6->sin6_addr); - ipver = "IPv6"; - } - char ipstr[INET6_ADDRSTRLEN]; - inet_ntop( it->ai_family, addr, ipstr, sizeof ipstr ); - - LOG( Logger::DEBUG, std::string(TToStr(counter)).append(". address is "). - append(ipver).append(": "). - append(ipstr).c_str() ); - } -} - - -bool TcpClient::connectToFirstAddress(struct addrinfo *servinfo) const -{ - TRACE; - - for ( struct addrinfo *it = servinfo; it != 0; it = it->ai_next) - if (::connect(m_socket, it->ai_addr, it->ai_addrlen) != -1) { - char hostBuffer[256]; - char serviceBuffer[256]; - int status = getnameinfo( it->ai_addr, it->ai_addrlen, - hostBuffer, sizeof(hostBuffer), - serviceBuffer, sizeof(serviceBuffer), - NI_NAMEREQD ); - - if ( status != 0 ) { - LOG( Logger::WARNING, std::string("Could not resolve hostname. "). - append(gai_strerror(status)).c_str() ); - } else { - LOG( Logger::DEBUG, std::string("Connected to "). - append(hostBuffer).append(":"). - append(serviceBuffer).c_str() ); - } - return true; - } - - LOG( Logger::ERR, std::string("Could not connect to host," - " connection refused.").c_str() ); - return false; -} - - TcpClient::WatcherThread::WatcherThread( TcpClient &data ) : m_tcpClient(data) { @@ -250,7 +106,7 @@ void* TcpClient::WatcherThread::run() if ( ret != 0 && !receive() ) { m_tcpClient.m_connected = false; m_tcpClient.onDisconnect(); - } + } } }