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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值