Socket类

/Socket.h/

#ifndef _SOCKET_H_
#define _SOCKET_H_

#include "MyException.h"    //异常类
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

class TCPSocket
{
protected:
    TCPSocket();
    virtual ~TCPSocket();
    bool  create();
    bool  bind(unsigned short int port,const char* ip=NULL)const;
    bool  listen(int backlog=SOMAXCONN) const;
    bool  accept(TCPSocket& ClientSocket)const;
    bool  connect(unsigned short int port,const char* ip) const;
    bool  reuseaddr() const;
    bool  isValid() const
    {
        return (m_sockfd!=-1);
    }
public:
    bool close();
    int  getfd() const
    {
        return m_sockfd;
    }
    bool  setNonBlocking(bool flag)const;
protected:
    int  m_sockfd;
};

/*** TCP Client***/
class TCPClient:public TCPSocket
{
private:
    struct Packet
    {
        unsigned int msgLen;
        char  text[1024];
    };
public:
    TCPClient(unsigned short int port,const char *ip)throw(ExceptionDerived);
    TCPClient();
    TCPClient(int clientfd);
    ~TCPClient();
    size_t send(const std::string& message)const throw(ExceptionDerived);
    size_t receive(std::string &message)const throw(ExceptionDerived);
    size_t read(void *buf,size_t count)throw(ExceptionDerived);
    void  write(const void* buf,size_t count)throw(ExceptionDerived);
    size_t write(const char* msg)throw(ExceptionDerived);   
};

/*** TCP Server ***/
class TCPServer:public TCPSocket
{
public:
    TCPServer(unsigned short int port,const char *ip=NULL,int);
    ~TCPServer();
    void accept(TCPClient &client)const throw(ExceptionDerived);
    TCPClient accept() const throw(ExceptionDerived);
};
#endif
#include "Socket.h"
TCPSocket::TCPSocket():m_sockfd(-1){}
TCPSocket::~TCPSocket()
{
    if(isValid())
        ::close(m_sockfd);
}

bool TCPSocket::create()
{
    if(isValid())
            return false;
    if((m_sockfd=::socket(AF_INET,SOCK_STREAM,0))==-1)
            return false;
    return true;
}

bool TCPSocket::bind(unsigned short int port,const char* ip)const
{
    if(!isValid())
        return false;
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    if(ip==NULL)
        addr.sin_addr.s_addr=htonl(INADDRY_ANY);
    else
        addr.sin_addr.s_addr=inet_addr(ip);
    if(::bind(m_sockfd,(const struct sockaddr*)&addr,sizeof(addr))==-1)
        return false;
    return true;    
}

bool TCPSocket::listen(int backlog)const
{
    if(!isValid())
        return false;
    if(::listen(m_sockfd,backlog)==-1)
        return false;
    return true;
}

bool TCPSocket::accept(TCPSocket &ClientSocket)const
{
    if(!isValid())
        return false;
    ClientSocket.m_sockfd=::accept(this->m_sockfd,NULL,NULL);
    if(ClientSocket.m_sockfd==-1)
        return false;
    return true;
}

bool TCPSocket::connect(unsigned short int port,const char* ip)const
{
    if(!isValid())
        return false;
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=inet_addr(ip);
    if(::connect(m_sockfd,(const struct sockaddr*)&addr,sizeof(addr))==-1)
        return false;
    return true;
}

bool TCPSocket::setNonBlocking(bool flag)const
{
    if(!isValid())
        return false;
    int opt=fcntl(m_sockfd,F_GETFL,0);
    if(opt==-1)
        return false;
    if(flag)
        opt|=O_NONBLOCK;
    else
        opt&=~O_NONBLOCK;
    if(fcntl(m_sockfd,F_SETFL,opt)==-1)
        return false;
    return true;
}

bool TCPSocket::reuseaddr() const
{
    if(!isValid())
        return false;
    int on=1;
    if(setsockopt(m_sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1)
        return false;
    return true;
}

bool TCPSocket::close()
{
    if(!isValid())
        return false;
    ::close(m_sockfd);
    m_sockfd=-1;
    return true;
}

/***Server TCP Socket***/
TCPServer::TCPServer(unsigned short int port,const char* ip,int backlog)throw(ExceptionDerived)
{
    if(create()==false)
        MY_THROW(ExceptionDerived,"tcp server create error");
    if(reuseaddr()==false)
        MY_THROW(ExceptionDerived,"tcp server reuseaddr error");
    if(bind(port,ip)==false)
        MY_THROW(ExceptionDerived,"tcp server bind error");
    if(listen(backlog)==false)
        MY_THROW(ExceptionDerived,"tcp server listen error");
}

TCPServer::~TCPServer(){}

void TCPServer::accept(TCPClient &client)const
    throw(ExceptionDerived)
{
    if(TCPSocket::accept(client)==-1)
        MY_THROW(ExceptionDerived,"tcp server accept error");       
}

TCPClient TCPServer::accept() const throw(ExceptionDerived)
{
    TCPClient client;
    if(TCPSocket::accept(client)==-1)
        MY_THROW(ExceptionDerived,"tcp server accept error");
    return client;
}

/*** TCP Client Socket ***/
TCPClient::TCPClient(unsigned short int port,const char* ip) throw(ExceptionDerived)
{
    if(create()==false)
        MY_THROW(ExceptionDerived,"tcp client create error");
    if(connect(port,ip)==false)
        MY_THROW(ExceptionDerived,"tcp client connect error");
}

TCPClient::~TCPClient(){}

TCPClient::TCPClient(int clientfd)
{
    if(clientfd<0)
        MY_THROW(ExceptionDerived,"tcp server create(parameter) error");
    m_sockfd=clientfd;
}

static ssize_t readn(int fd,void *buf,size_t count);
static ssize_t writen(int fd,const void* buf,size_t count);

size_t TCPClient::send(const std::string& message)const throw(ExceptionDerieved)
{
    Packet buf;
    buf.msgLen=htonl(message.length());
    strcpy(buf.text,message.c_str());
    if(writen(m_sockfd,&buf,sizeof(buf.msgLen)+message.length())==-1)
        MY_THROW(ExceptionDerived,"tcp client writen error");
    return message.length();
}

size_t TCPClient::receive(std::string& message)const throw(ExceptionDerived)
{
    Packet buf={0,0};
    size_t readBytes=readn(m_sockfd,&buf.msgLen,sizeof(buf.msgLen));
    if(readBytes==(size_t)-1)
        MY_THROW(ExceptionDerived,"tcp client readn error");
    else if(readBytes !=sizeof(buf.msgLen))
        MY_THROW(ExceptionDerived,"perr connect closed");

    unsigned int lenHost=ntohl(buf.msgLen);
    readBytes=readn(m_sockfd,buf.text,lenHost);
    if(readBytes==(size_t)-1)
        MY_THROW(ExceptionDerived,"tcp client readn error");
    else if(readBytes!=lenHost)
        MY_THROW(ExceptionDerived,"peer connect error");
    message=buf.text;
    return message.length();
}

size_t TCPClient::read(void *buf,size_t count)throw(ExceptionDerived)
{
    size_t readBytes=::read(m_sockfd,buf,count);
    if(readBytes==-1)
        MY_THROW(ExceptionDerived,"tcp client read error");
    return (size_t)readBytes;
}

void TCPClient::write(const void *buf,size_t count)throw(ExceptionDerived)
{
    if(::write(m_sockfd,buf,count)==-1)
        MY_THROW(ExceptionDerived,"tcp client write error");
}

size_t TCPClient::write(const char* msg)throw(ExceptionDerived)
{
    if(::write(m_sockfd,msg,strlen(msg))==-1)
        MY_THROW(ExceptionDerived,"tcp client write error");
    return strlen(msg);
}

static ssize_t readn(int fd,void *buf,size_t count)
{
    size_t nLeft=count;
    ssize_t nRead=0;
    char *pBuf=(char*)buf;
    while(nLeft>0)
    {
        if((nRead=read(fd,pBuf,nLeft))<0)
        {
                if(errno==EINTR)
                    continue;
                else
                    return -1;
        }
        else if(nRead==0)
            return count-nLeft;
        nLeft-=nRead;
        pBuf+=nRead;
    }
    return count;
}

static ssize_t writen(int fd,const void* buf,size_t count)
{
    size_t nLeft=count;
    size_t nWritten=0;
    while(nLeft>0)
    {
        if((nWritten=write(fd,pBuf,nLeft))<0)
        {
            if(errno==EINTR)
                continue;
            else
                return -1;
        }
        else if(nWritten==0)
            continue;
        nLeft-=nWritten;
        pBuf+=nWritten;
    }
    return count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值