//
// File: client.h
// Author: root
//
// Created on February 19, 2008, 9:36 AM
//
#ifndef _CLIENT_H
#define _CLIENT_H
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
class client{
public:
enum {BUFFERSIZE = 1024};
client(int fd,struct sockaddr_in sinaddr,int timeout);
~client();
bool update();
string _value;
private:
int _fd;
int _timeout;
char *buffer;
};
#endif /* _CLIENT_H */
#include "client.h"
client::client(int fd, sockaddr_in sinaddr, int timeout){
_fd = fd;
_timeout = timeout;
fcntl( _fd, F_SETFL, fcntl( _fd, F_GETFL ) | O_NONBLOCK );
buffer = NULL;
buffer = new char[BUFFERSIZE];
}
client::~client(){
close(_fd);
delete buffer;
buffer = NULL;
}
bool client::update(){
fd_set fdClient;
FD_ZERO( &fdClient );
FD_SET( _fd, &fdClient );
struct timeval tv;
tv.tv_sec = _timeout;
tv.tv_usec = 0;
if( select( _fd + 1, &fdClient, NULL, NULL, &tv ) == -1 ) {
return true;
}
if( FD_ISSET( _fd, &fdClient ) ) {
memset( buffer, 0, sizeof( char ) * BUFFERSIZE );
int c = recv( _fd, buffer, BUFFERSIZE, 0 );
if( c == -1 && errno != EWOULDBLOCK ) {
if( errno != ECONNRESET )
cout << "peer reset the connection" << endl;
return true;
}
else if( c == 0 )
return true;
else if( c > 0 ) {
_value = string( buffer, c );
cout << _value << endl;
}
else {
return true;
}
}
return false;
}
//
// File: server.h
// Author: root
//
// Created on February 19, 2008, 9:34 AM
//
#ifndef _SERVER_H
#define _SERVER_H
#include <vector>
#include <iostream>
#include <string>
#include "client.h"
using namespace std;
class server{
public:
server(int port);
~server();
bool update(bool block);
vector<client *> clients;
enum {MAXCLIENTS = 11};
void kill(){
_kill = true;
}
private:
int _fd;
bool _kill;
};
#endif /* _SERVER_H */
#include "server.h"
server::server(int port = 10000){
_kill = false;
struct sockaddr_in sin;
memset( &sin, 0, sizeof( sin ) );
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
_fd = socket( PF_INET, SOCK_STREAM, 0 );
int optval = 1;
setsockopt( _fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof( int ) );
if( bind( _fd, (struct sockaddr *)&sin, sizeof( sin ) ) == -1 ) {
cout << "bind error" << endl;
}
// listen, queue length 8
if( listen( _fd, 8 ) == -1 ) {
cout << "listen error" << endl;
//exit( 1 );
}
}
server::~server(){
close(_fd);
for( vector<client *> :: iterator i = clients.begin( ); i != clients.end( ); i++ )
delete *i;
clients.clear( );
}
bool server::update(bool block){
if( clients.size( ) < MAXCLIENTS ) {
fd_set fdServer;
FD_ZERO( &fdServer );
FD_SET( _fd, &fdServer );
struct timeval tv;
if( block ) {
// block for 100 ms to keep from eating up all cpu time
tv.tv_sec = 0;
tv.tv_usec = 100000;
}
else {
tv.tv_sec = 0;
tv.tv_usec = 0;
}
if( select( _fd + 1, &fdServer, NULL, NULL, &tv ) == -1 )
{
FD_ZERO( &fdServer );
usleep( 100 );
}
if( FD_ISSET( _fd, &fdServer ) ) {
struct sockaddr_in adrFrom;
int iAddrLen = sizeof( adrFrom );
int sckClient;
if( ( sckClient = accept( _fd, (struct sockaddr *)&adrFrom, (socklen_t *)&iAddrLen ) ) == -1 )
cout << "accept error" << endl;
else{
clients.push_back( new client( sckClient, adrFrom, 0) );
cout << "clients comes" << endl;
}
}
}
else {
// maximum connections reached
usleep( 100 );
}
// process
for( vector<client *> :: iterator i = clients.begin( ); i != clients.end( ); ) {
if( (*i)->update( ) ) {
delete *i;
i = clients.erase( i );
cout << "clients exit" << endl;
}
else
i++;
}
return _kill;
}