`
isiqi
  • 浏览: 16138495 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Socket 封装类

阅读更多

//
// 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;
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics