TcpClient listens to reply with poll on a separate thread

master
Denes Matetelki 13 years ago
parent d6e130aa30
commit 76424b75f4

2
.gitignore vendored

@ -21,3 +21,5 @@ gdb.out
html/* html/*
test/testCppUtils test/testCppUtils
test/testCppUtils.out test/testCppUtils.out
*.kate-swp

@ -1,6 +1,8 @@
#ifndef TCP_CLIENT_HPP #ifndef TCP_CLIENT_HPP
#define TCP_CLIENT_HPP #define TCP_CLIENT_HPP
#include "Thread.hpp"
#include <string> #include <string>
#include <sys/types.h> #include <sys/types.h>
@ -16,29 +18,44 @@ public:
TcpClient ( const std::string host, TcpClient ( const std::string host,
const std::string port ); const std::string port );
~TcpClient(); virtual ~TcpClient();
bool connect(); bool connect();
bool disconnect(); bool disconnect();
bool send(const std::string msg); bool send(const std::string msg);
bool receive(std::string &reply);
private: private:
virtual void msgArrived(const std::string) = 0;
virtual void onDisconnect() = 0;
class WatcherThread : public Thread
{
public:
WatcherThread( TcpClient &data );
private:
void* run();
bool receive();
TcpClient &m_tcpClient;
};
bool openSocket(); bool openSocket();
bool closeSocket(); bool closeSocket();
bool connectToHost(); bool connectToHost();
bool getHostInfo(struct addrinfo **servinfo); bool getHostInfo(struct addrinfo **servinfo) const;
void printHostDetails(struct addrinfo *servinfo); void printHostDetails(struct addrinfo *servinfo) const;
bool connectToFirstAddress(struct addrinfo *servinfo); bool connectToFirstAddress(struct addrinfo *servinfo) const;
int m_socket; int m_socket;
std::string m_host; std::string m_host;
std::string m_port; std::string m_port;
bool m_connected; bool m_connected;
WatcherThread m_watcher;
}; };

@ -7,21 +7,50 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
class PrinterTcpClient : public TcpClient
{
public:
PrinterTcpClient ( const std::string host,
const std::string port )
: TcpClient(host, port)
{
TRACE;
}
private:
void msgArrived( const std::string msg)
{
TRACE;
LOG( Logger::DEBUG, std::string("Got msg: ").append(msg).c_str() );
}
void onDisconnect()
{
TRACE;
LOG( Logger::DEBUG, "What shall I do..." );
}
};
int main( int argc, char * argv[] ) int main( int argc, char * argv[] )
{ {
Logger::createInstance(); Logger::createInstance();
Logger::init(std::cout); Logger::init(std::cout);
Logger::setLogLevel(Logger::FINEST); Logger::setLogLevel(Logger::FINEST);
TcpClient tcpclient("localhost", "4455"); PrinterTcpClient tcpclient("localhost", "4455");
tcpclient.connect(); tcpclient.connect();
sleep(2);
tcpclient.send("madao"); tcpclient.send("madao");
sleep(2);
std::string reply; // std::string reply;
tcpclient.receive(reply); // tcpclient.receive(reply);
std::cout << "got reply \"" << reply << "\"" << std::endl; // std::cout << "got reply \"" << reply << "\"" << std::endl;
tcpclient.disconnect(); tcpclient.disconnect();

@ -7,6 +7,8 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h> // inet_ntop #include <arpa/inet.h> // inet_ntop
#include <poll.h>
TcpClient::TcpClient( const std::string host, TcpClient::TcpClient( const std::string host,
const std::string port ) const std::string port )
@ -14,8 +16,11 @@ TcpClient::TcpClient( const std::string host,
, m_host(host) , m_host(host)
, m_port(port) , m_port(port)
, m_connected(false) , m_connected(false)
, m_watcher(*this)
{ {
TRACE; TRACE;
m_watcher.start();
} }
TcpClient::~TcpClient() TcpClient::~TcpClient()
@ -23,6 +28,9 @@ TcpClient::~TcpClient()
TRACE; TRACE;
disconnect(); disconnect();
m_watcher.stop();
m_watcher.join();
} }
@ -66,22 +74,6 @@ bool TcpClient::send(const std::string msg)
} }
bool TcpClient::receive(std::string &reply)
{
TRACE;
char buffer[256];
ssize_t n = read(m_socket, buffer, 255);
if (n == -1) {
LOG( Logger::ERR, errnoToString("ERROR reading from socket. ").c_str() );
return false;
}
reply = std::string(buffer, n);
return true;
}
bool TcpClient::openSocket() bool TcpClient::openSocket()
{ {
TRACE; TRACE;
@ -136,7 +128,7 @@ bool TcpClient::connectToHost()
} }
bool TcpClient::getHostInfo(struct addrinfo **servinfo) bool TcpClient::getHostInfo(struct addrinfo **servinfo) const
{ {
TRACE; TRACE;
@ -166,7 +158,7 @@ bool TcpClient::getHostInfo(struct addrinfo **servinfo)
} }
void TcpClient::printHostDetails(struct addrinfo *servinfo) void TcpClient::printHostDetails(struct addrinfo *servinfo) const
{ {
TRACE; TRACE;
@ -196,7 +188,7 @@ void TcpClient::printHostDetails(struct addrinfo *servinfo)
} }
bool TcpClient::connectToFirstAddress(struct addrinfo *servinfo) bool TcpClient::connectToFirstAddress(struct addrinfo *servinfo) const
{ {
TRACE; TRACE;
@ -224,3 +216,68 @@ bool TcpClient::connectToFirstAddress(struct addrinfo *servinfo)
" connection refused.").c_str() ); " connection refused.").c_str() );
return false; return false;
} }
TcpClient::WatcherThread::WatcherThread( TcpClient &data )
: m_tcpClient(data)
{
TRACE;
}
void* TcpClient::WatcherThread::run()
{
TRACE;
while ( m_isRunning ) {
struct timespec tm = {0,1000};
nanosleep(&tm, &tm) ;
if ( m_tcpClient.m_connected ) {
pollfd fds[1] ;
fds[0].fd = m_tcpClient.m_socket ;
fds[0].events = POLLIN | POLLPRI ;
fds[0].revents = 0 ;
int ret = poll( fds , 1, 1000) ;
if ( ret == -1 ) {
LOG( Logger::ERR, errnoToString("ERROR at polling. ").c_str() );
m_tcpClient.m_connected = false;
m_tcpClient.onDisconnect();
}
if ( ret != 0 && !receive() ) {
m_tcpClient.m_connected = false;
m_tcpClient.onDisconnect();
}
}
}
return 0;
}
bool TcpClient::WatcherThread::receive()
{
TRACE;
char buffer[256];
int len = recv( m_tcpClient.m_socket, buffer , 256, 0) ;
if (len == -1) {
LOG( Logger::ERR, errnoToString("ERROR reading from socket. ").c_str() );
return false;
}
if (len == 0) {
LOG( Logger::DEBUG, "Connection closed by peer." );
return false;
}
std::string msg(buffer, len);
m_tcpClient.msgArrived(msg);
return true;
}
Loading…
Cancel
Save