From 3bd18621c636729aea93898af7bb3b1eb9acd41d Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Mon, 31 Oct 2011 20:06:44 +0100 Subject: [PATCH] socket clients --- include/inetSocketClient.hpp | 27 +++++++++++++ include/localSocketClient.hpp | 27 +++++++++++++ include/socketClient.hpp | 36 +++++++++++++++++ src/inetSocketClient.cpp | 46 +++++++++++++++++++++ src/localSocketClient.cpp | 34 ++++++++++++++++ src/socketClient.cpp | 75 +++++++++++++++++++++++++++++++++++ 6 files changed, 245 insertions(+) create mode 100644 include/inetSocketClient.hpp create mode 100644 include/localSocketClient.hpp create mode 100644 include/socketClient.hpp create mode 100644 src/inetSocketClient.cpp create mode 100644 src/localSocketClient.cpp create mode 100644 src/socketClient.cpp diff --git a/include/inetSocketClient.hpp b/include/inetSocketClient.hpp new file mode 100644 index 0000000..05cc429 --- /dev/null +++ b/include/inetSocketClient.hpp @@ -0,0 +1,27 @@ +#ifndef INET_SOCKET_CLIENT_HPP +#define INET_SOCKET_CLIENT_HPP + +#include "socketClient.hpp" + +class InetSocketClient : public SocketClient +{ +public: + + InetSocketClient( const std::string host, + const int port ); + + ~InetSocketClient(); + + +private: + + bool connectToPeer(void); + + std::string m_host; + int m_port; + struct sockaddr_in m_serverAddr; + +}; + + +#endif // INET_SOCKET_CLIENT_HPP diff --git a/include/localSocketClient.hpp b/include/localSocketClient.hpp new file mode 100644 index 0000000..19ce0c3 --- /dev/null +++ b/include/localSocketClient.hpp @@ -0,0 +1,27 @@ +#ifndef LOCAL_SOCKET_CLIENT_HPP +#define LOCAL_SOCKET_CLIENT_HPP + +#include "socketClient.hpp" + +#include + +class LocalSocketClient : public SocketClient +{ +public: + + LocalSocketClient( const std::string sockPath); + + ~LocalSocketClient(); + + +private: + + bool connectToPeer(void); + + std::string m_sockPath; + struct sockaddr_un m_remote; + +}; + + +#endif // LOCAL_SOCKET_CLIENT_HPP diff --git a/include/socketClient.hpp b/include/socketClient.hpp new file mode 100644 index 0000000..c6b4ac9 --- /dev/null +++ b/include/socketClient.hpp @@ -0,0 +1,36 @@ +#ifndef SOCKET_CLIENT_HPP +#define SOCKET_CLIENT_HPP + +#include + +#include +#include +#include +#include + +class SocketClient +{ +public: + + SocketClient( const int addrDomain, + const int socketType); + + virtual ~SocketClient(); + + bool send(const std::string msg); + bool receive(std::string &reply); + +protected: + + bool connect(void); + virtual bool connectToPeer(void) = 0; + std::string errorToString(const char *s) const; + + bool m_connected; + int m_addrDomain; + int m_socketType; + int m_socketfd; +}; + + +#endif // SOCKET_CLIENT_HPP diff --git a/src/inetSocketClient.cpp b/src/inetSocketClient.cpp new file mode 100644 index 0000000..382f8ae --- /dev/null +++ b/src/inetSocketClient.cpp @@ -0,0 +1,46 @@ +#include "inetSocketClient.hpp" + +#include + +#include // memset, memcpy + + +InetSocketClient::InetSocketClient(const std::string host, + const int port) + : SocketClient( AF_INET, SOCK_STREAM ) + , m_host(host) + , m_port(port) + , m_serverAddr() +{ + +} + + +InetSocketClient::~InetSocketClient() +{ + +} + + +bool InetSocketClient::connectToPeer() +{ + struct hostent *server = gethostbyname(m_host.c_str()); + if (server == 0) { + std::cerr << errorToString("ERROR, no such host. ") << std::endl; + return false; + } + + m_serverAddr.sin_family = AF_INET; + m_serverAddr.sin_port = htons(m_port); + memcpy(&m_serverAddr.sin_addr.s_addr, server->h_addr, server->h_length); + + if ( ::connect( m_socketfd, + (struct sockaddr *) &m_serverAddr, + sizeof(m_serverAddr)) == -1) { + std::cerr << errorToString("ERROR connecting to peer. ") << std::endl; + return false; + } + + m_connected = true; + return true; +} diff --git a/src/localSocketClient.cpp b/src/localSocketClient.cpp new file mode 100644 index 0000000..4be97ae --- /dev/null +++ b/src/localSocketClient.cpp @@ -0,0 +1,34 @@ +#include "localSocketClient.hpp" + +#include +#include + +LocalSocketClient::LocalSocketClient(const std::string sockPath) + : SocketClient( AF_UNIX, SOCK_STREAM ) + , m_sockPath(sockPath) + , m_remote() +{ + +} + + +LocalSocketClient::~LocalSocketClient() +{ + +} + + +bool LocalSocketClient::connectToPeer(void) +{ + m_remote.sun_family = AF_UNIX; + strcpy(m_remote.sun_path, m_sockPath.c_str()); + int len = strlen(m_remote.sun_path) + sizeof(m_remote.sun_family); + + if ( ::connect(m_socketfd, (struct sockaddr *)&m_remote, len) == -1) { + std::cerr << errorToString("ERROR connecting to peer. ") << std::endl; + return false; + } + + m_connected = true; + return true; +} diff --git a/src/socketClient.cpp b/src/socketClient.cpp new file mode 100644 index 0000000..2cab8e1 --- /dev/null +++ b/src/socketClient.cpp @@ -0,0 +1,75 @@ +#include "socketClient.hpp" + +#include // errno +#include // strerror + +#include + + +SocketClient::SocketClient( const int addrDomain, + const int socketType ) + : m_connected(false) + , m_addrDomain(addrDomain) + , m_socketType(socketType) + , m_socketfd(0) +{ +} + + +SocketClient::~SocketClient() +{ + if ( m_connected && close(m_socketfd) == -1 ) + std::cerr << errorToString("ERROR closing socket. ") << std::endl; +} + + +bool SocketClient::send(const std::string msg) +{ + if ( !m_connected && !this->connect() ) + return false; + + ssize_t n = write(m_socketfd, msg.c_str(), msg.length()); + if (n == -1) { + std::cerr << errorToString("ERROR writing to socket. ") << std::endl; + return false; + } else if ( n < (ssize_t)msg.length() ) { + std::cerr << "Only a part of msg has been written to socket. " << std::endl; + return false; + } + + return true; +} + + +bool SocketClient::receive(std::string &reply) +{ + if ( !m_connected && !this->connect() ) + return false; + + char buffer[256]; + ssize_t n = read(m_socketfd, buffer, 255); + if (n == -1) { + std::cerr << errorToString("ERROR reading from socket. ") << std::endl; + return false; + } + reply = std::string(buffer, n); + + return true; +} + + +bool SocketClient::connect(void) +{ + m_socketfd = socket(m_addrDomain, m_socketType, 0); + if ( m_socketfd == -1 ) { + std::cerr << errorToString("ERROR opening socket. ") << std::endl; + return false; + } + + return connectToPeer(); +} + +std::string SocketClient::errorToString(const char *s) const +{ + return std::string(s).append(strerror(errno)); +} \ No newline at end of file