parent
8d02e474b8
commit
b1d47a8978
@ -0,0 +1,45 @@
|
||||
#ifndef TCP_SERVER_HPP
|
||||
#define TCP_SERVER_HPP
|
||||
|
||||
#include "Socket.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <poll.h>
|
||||
|
||||
class TcpServer : public Socket
|
||||
{
|
||||
public:
|
||||
|
||||
TcpServer ( const std::string host,
|
||||
const std::string port,
|
||||
const int maxClients = 5 );
|
||||
|
||||
virtual ~TcpServer();
|
||||
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
virtual void msgArrived(const int clientSocket,
|
||||
const std::string msg) = 0;
|
||||
|
||||
private:
|
||||
|
||||
TcpServer(const TcpServer&);
|
||||
TcpServer& operator=(const TcpServer&);
|
||||
|
||||
bool receive(const int clientSocket);
|
||||
|
||||
void addFd( int fd, short events );
|
||||
void removeFd( int fd );
|
||||
|
||||
std::string m_host;
|
||||
std::string m_port;
|
||||
nfds_t m_maxclients;
|
||||
bool m_running;
|
||||
pollfd *m_fds;
|
||||
nfds_t m_num_of_fds;
|
||||
sockaddr m_addr;
|
||||
socklen_t m_addrLen;
|
||||
};
|
||||
|
||||
#endif // TCP_SERVER_HPP
|
@ -0,0 +1,49 @@
|
||||
// gpp tcpServer_main.cpp -o client -I../include ../src/Logger.cpp ../src/TcpClient.cpp
|
||||
|
||||
#include "TcpServer.hpp"
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
class EchoTcpServer : public TcpServer
|
||||
{
|
||||
public:
|
||||
|
||||
EchoTcpServer ( const std::string host,
|
||||
const std::string port,
|
||||
const int maxClients = 5 )
|
||||
: TcpServer(host, port, maxClients)
|
||||
{
|
||||
TRACE;
|
||||
}
|
||||
|
||||
void msgArrived(const int clientSocket,
|
||||
const std::string msg)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
LOG( Logger::DEBUG, std::string("Got msg: ").append(msg).c_str() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
Logger::createInstance();
|
||||
Logger::init(std::cout);
|
||||
Logger::setLogLevel(Logger::FINEST);
|
||||
|
||||
EchoTcpServer tcpServer("localhost", "4455");
|
||||
|
||||
tcpServer.start();
|
||||
|
||||
sleep(10);
|
||||
|
||||
tcpServer.stop();
|
||||
|
||||
Logger::destroy();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
#include "TcpServer.hpp"
|
||||
|
||||
#include "Logger.hpp"
|
||||
#include "Common.hpp"
|
||||
|
||||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
TcpServer::TcpServer( const std::string host,
|
||||
const std::string port,
|
||||
const int maxClients )
|
||||
: Socket(AF_INET, SOCK_STREAM)
|
||||
, m_host(host)
|
||||
, m_port(port)
|
||||
, m_maxclients(maxClients)
|
||||
, m_running(false)
|
||||
, m_fds(0)
|
||||
, m_num_of_fds(0)
|
||||
, m_addr()
|
||||
, m_addrLen(0)
|
||||
{
|
||||
TRACE;
|
||||
m_fds = (pollfd*) malloc (sizeof(struct pollfd)*m_maxclients);
|
||||
}
|
||||
|
||||
|
||||
TcpServer::~TcpServer()
|
||||
{
|
||||
TRACE;
|
||||
free(m_fds);
|
||||
}
|
||||
|
||||
|
||||
bool TcpServer::start()
|
||||
{
|
||||
TRACE;
|
||||
|
||||
if ( !openSocket() )
|
||||
return false;
|
||||
|
||||
if ( !bindToHost(m_host, m_port) )
|
||||
return false;
|
||||
|
||||
if ( listen(m_socket, 64) == -1 ) {
|
||||
LOG( Logger::ERR, errnoToString("ERROR listening. ").c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
addFd( m_socket, POLLIN | POLLPRI ) ;
|
||||
|
||||
m_running = true;
|
||||
|
||||
struct timespec tm = {0,1000};
|
||||
|
||||
while ( m_running ) {
|
||||
|
||||
nanosleep(&tm, &tm) ;
|
||||
int ret = poll( m_fds , m_maxclients, 1000);
|
||||
|
||||
if ( ret == -1 ) {
|
||||
LOG( Logger::ERR, errnoToString("ERROR polling. ").c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ret == 0 ) // timeout
|
||||
continue;
|
||||
|
||||
for ( nfds_t i = 0; i < m_num_of_fds; ++i ) {
|
||||
if ( m_fds[i].revents != 0 ) {
|
||||
|
||||
if ( m_fds[i].fd == m_socket ) {
|
||||
|
||||
sockaddr clientAddr;
|
||||
socklen_t clientAddrLen;
|
||||
int client_socket = accept( m_socket, &clientAddr, &clientAddrLen ) ;
|
||||
|
||||
if ( client_socket == -1 ) {
|
||||
LOG( Logger::ERR, errnoToString("ERROR accepting. ").c_str() );
|
||||
} else {
|
||||
|
||||
std::string clientAddress, clientService;
|
||||
if ( Socket::convertNameInfo(&clientAddr, clientAddrLen,
|
||||
clientAddress, clientService ) ) {
|
||||
LOG( Logger::DEBUG, std::string("New client connected: ").
|
||||
append(clientAddress).append(":").
|
||||
append(clientService).c_str() );
|
||||
}
|
||||
addFd( client_socket, POLLIN | POLLPRI );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( !receive( m_fds[i].fd ) ) {
|
||||
removeFd(m_fds[i].fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TcpServer::stop()
|
||||
{
|
||||
TRACE;
|
||||
|
||||
m_running = false;
|
||||
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
|
||||
bool TcpServer::receive(const int clientSocket)
|
||||
{
|
||||
TRACE;
|
||||
|
||||
char buffer[256];
|
||||
int len = recv( clientSocket, 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);
|
||||
msgArrived(clientSocket, msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TcpServer::addFd( int fd, short events )
|
||||
{
|
||||
TRACE;
|
||||
|
||||
if (m_num_of_fds < m_maxclients )
|
||||
{
|
||||
m_fds[m_num_of_fds].fd = fd ;
|
||||
m_fds[m_num_of_fds].events = events ;
|
||||
m_fds[m_num_of_fds].revents = 0 ;
|
||||
++m_num_of_fds ;
|
||||
}
|
||||
}
|
||||
|
||||
void TcpServer::removeFd( int fd )
|
||||
{
|
||||
TRACE;
|
||||
|
||||
unsigned int i = 0 ;
|
||||
while (i < m_maxclients && m_fds[i].fd != fd ) ++i ;
|
||||
|
||||
if ( i != m_maxclients ) {
|
||||
for ( ; i < m_maxclients - 1; ++i )
|
||||
m_fds[i] = m_fds[i+1] ;
|
||||
|
||||
m_fds[i].fd = 0 ;
|
||||
m_fds[i].events = 0 ;
|
||||
m_fds[i].revents = 0 ;
|
||||
--m_num_of_fds ;
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
#include "socketClient.hpp"
|
||||
|
||||
#include <errno.h> // errno
|
||||
#include <string.h> // strerror
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
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::errnoToString(const char *s)
|
||||
{
|
||||
return std::string(s).append(strerror(errno));
|
||||
}
|
Loading…
Reference in new issue