C++网络编程读书笔记2—类的封装

 服务器客户端通信—类的封装

#ifndef _YFY_ADDR_H
#define _YFY_ADDR_H

#include <sys/types.h>
#include <sys/socket.h>
#include   <netinet/in.h> 
#include   <netdb.h> 
#include   <sys/stat.h> 
#include   <fcntl.h> 
#include   <dirent.h> 
#include   <sys/time.h> 
#include   <unistd.h> 
#include   <errno.h> 
#include   <net/if.h> 
#include   <arpa/inet.h>
#include <string.h>

#define DEFAULT_PORT 8890

class YFY_Addr
{
public:
    YFY_Addr(int type = AF_INET, char *ip = 0, unsigned int port = DEFAULT_PORT);
    void setFamily(sa_family_t );
    void setPort(unsigned int port);
    void setIp(const char *str_ip);
    void setIp(unsigned int ip);
    bool operator == (const YFY_Addr &sap) const;
    bool operator !=(const YFY_Addr &sap)const;
    unsigned int getPort();
    void getIp(const char * str_ip);
    unsigned int getSize() const;
    const void *getAddr() const;
    struct sockaddr * convert() const;
	
private:
    struct sockaddr_in _addr;
};
#endif
#include "../inc/YFY_Addr.h"
	
YFY_Addr::YFY_Addr(int type/* = AF_INET*/, char *ip/* = 0*/, unsigned int port/* = DEFAULT_PORT*/)
{
    bzero(&_addr, sizeof(_addr));
    _addr.sin_family = type;
    if(ip)
        _addr.sin_addr.s_addr = inet_addr(ip);
    else
        _addr.sin_addr.s_addr = htonl(INADDR_ANY);
    _addr.sin_port = htons(port);
}

void YFY_Addr::setFamily(sa_family_t family)
{
    _addr.sin_family = family;
}

void YFY_Addr::setPort(unsigned int port)
{
    _addr.sin_port = htons(port);
}

void YFY_Addr::setIp(const char * str_ip)
{
    if(0 == str_ip || 0 == strcmp("hostname", str_ip))
        _addr.sin_addr.s_addr = htonl(INADDR_ANY);
    else
        _addr.sin_addr.s_addr = inet_addr(str_ip);
}

void YFY_Addr::setIp(unsigned int ip)
{
    _addr.sin_addr.s_addr = htonl(ip);
}

bool YFY_Addr::operator==(const YFY_Addr &sap) const
{

    return 0 == memcmp(&_addr, sap.getAddr(), sap.getSize());
}

bool YFY_Addr::operator!=(const YFY_Addr &sap) const
{

    return 0 != memcmp(&_addr, sap.getAddr(), sap.getSize());
}

unsigned int YFY_Addr::getSize() const
{
    return sizeof(_addr);
}

const void * YFY_Addr::getAddr() const
{
    return &_addr;
}

struct sockaddr * YFY_Addr::convert() const
{
    return (struct sockaddr *)&_addr;
}

#ifndef _YFY_SOCKET_H
#define _YFY_SOCKET_H

#include <sys/types.h>
#include <sys/socket.h>
#include "YFY_Addr.h"

class YFY_Socket
{
public:
    int setOption(int level, int  opt_type, const void *optval, socklen_t optlen);
    int getOption(int level, int  opt_type, void *optval, socklen_t *optlen);
    int close();
    int getFileDescriptor();
    void setFileDescriptor(int sock);
    int getLocalAddr(YFY_Addr &) const;
    int getRemoteAddr(YFY_Addr &) const;
	
protected:
    YFY_Socket();
    ~YFY_Socket();
	
protected:
    int _sockfd;
};
#endif
#include "../inc/YFY_Socket.h"

YFY_Socket::YFY_Socket()
{
}

YFY_Socket::~YFY_Socket()
{
}

void YFY_Socket::setFileDescriptor(int sock)
{
    _sockfd = sock;

}

int YFY_Socket::getFileDescriptor()
{
    return _sockfd;

}

int YFY_Socket::setOption(int level, int opt_type, const void * optval, socklen_t optlen)
{
    setsockopt(_sockfd, level, opt_type, optval, optlen);
}

int YFY_Socket::getOption(int level, int opt_type, void * optval, socklen_t * optlen)
{

    getsockopt(_sockfd, level, opt_type, optval, optlen);
}

int YFY_Socket::close()
{
    return ::close(_sockfd);
}

int YFY_Socket::getLocalAddr(YFY_Addr & addr) const
{
    struct sockaddr_in local_addr;
    socklen_t addrlen;

    if(0 == getsockname(_sockfd, (struct sockaddr *)&local_addr, &addrlen))
    {        
        addr.setFamily(local_addr.sin_family);
        addr.setIp(local_addr.sin_addr.s_addr);
        addr.setPort(local_addr.sin_port);
    }
}

int YFY_Socket::getRemoteAddr(YFY_Addr & addr) const
{
    struct sockaddr_in peer_addr;
    socklen_t addrlen;

    if(0 == getpeername(_sockfd, (struct sockaddr *)&peer_addr, &addrlen))
    {
        addr.setFamily(peer_addr.sin_family);
        addr.setIp(peer_addr.sin_addr.s_addr);
        addr.setPort(peer_addr.sin_port);
    }
}

#ifndef _YFY_SOCK_ACCEPTOR_H
#define _YFY_SOCK_ACCEPTOR_H

#include "YFY_Addr.h"
#include "YFY_Tcp_Socket.h"

class YFY_Sock_Acceptor
{

public:
    YFY_Sock_Acceptor(YFY_Tcp_Socket * sock = 0);
    ~YFY_Sock_Acceptor();
    int open(YFY_Addr * addr);
    void setSocket(YFY_Tcp_Socket *sock = 0);
    YFY_Tcp_Socket *accept();
	
private:
    YFY_Tcp_Socket *_sock;
    YFY_Addr * _addr;
};
#endif
#include "../inc/YFY_Sock_Acceptor.h"

YFY_Sock_Acceptor::YFY_Sock_Acceptor(YFY_Tcp_Socket * sock/* = 0*/)
{
    _sock = sock;
}

YFY_Sock_Acceptor::~YFY_Sock_Acceptor()
{
}

int YFY_Sock_Acceptor::open(YFY_Addr *addr)
{
    _addr = addr;
    if(0 != bind(_sock->getFileDescriptor(), addr->convert(), addr->getSize()))
        return -1;
    if(0 != listen(_sock->getFileDescriptor(), 1))
        return -1;
    return 0;
}

void YFY_Sock_Acceptor::setSocket(YFY_Tcp_Socket * sock/* = 0*/)
{
    _sock = sock;
}

YFY_Tcp_Socket * YFY_Sock_Acceptor::accept()
{
    int peer_fd;
    unsigned int addr_len;
    YFY_Tcp_Socket *nsock = 0;

    peer_fd = ::accept(_sock->getFileDescriptor(), _addr->convert(), &addr_len);
    if(-1 == peer_fd)
        return 0;
    nsock = new YFY_Tcp_Socket(peer_fd);

    return nsock;
}
#ifndef _YFY_SOCK_CONNECTOR_H
#define _YFY_SOCK_CONNECTOR_H

#include "../inc/YFY_Addr.h"
#include "../inc/YFY_Time_Value.h"
#include "../inc/YFY_Tcp_Socket.h"

class YFY_Sock_Connector
{
public:
    YFY_Sock_Connector();
    ~YFY_Sock_Connector();
    /*non-block*/
    int connect(YFY_Addr & serv_addr, YFY_Tcp_Socket &serv_sock, YFY_Time_Value  *time = 0);
};
#endif
#include "../inc/YFY_Sock_Connector.h"

YFY_Sock_Connector::YFY_Sock_Connector()
{
}

YFY_Sock_Connector::~YFY_Sock_Connector()
{
}

int YFY_Sock_Connector::connect(YFY_Addr & serv_addr, YFY_Tcp_Socket & serv_sock, YFY_Time_Value * timeout/* = 0*/)
{
    int flags;
    int sockfd;
    int n;
    int error;
    int result;
    socklen_t len;
    fd_set rset, wset;
    struct timeval tvalue;

    sockfd = serv_sock.getFileDescriptor();
    if(!timeout)
        return ::connect(sockfd, serv_addr.convert(), serv_addr.getSize());
	
    else
    {
        flags = fcntl(sockfd, F_GETFL, 0);
        fcntl(sockfd,  F_SETFL, flags | O_NONBLOCK);

        result = ::connect(sockfd, serv_addr.convert(), serv_addr.getSize());
        if(result != EINPROGRESS)
            return -1;
        if(0 == result)
            return 0;

        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
        wset = rset;
        tvalue.tv_sec = timeout->getSec();
        tvalue.tv_usec = timeout->getUsec();

        n = select(sockfd + 1, &rset, &wset, NULL, &tvalue);
        if(!n)
        {
            serv_sock.close();
            return -1;
        }
        if(FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset))
        {
            len = sizeof(error);
            if(serv_sock.getOption(SOL_SOCKET, SO_ERROR, &error, &len) < 0)
                return -1;
        }
        else
            return -1;

        fcntl(sockfd, F_SETFL, flags);
        if(error)
        {
            serv_sock.close();
            return -1;
        }
        return 0;
    }
}
#ifndef _YFY_TCP_SOCKET_H
#define _YFY_TCP_SOCKET_H

#include "../inc/YFY_Time_Value.h"
#include "../inc/YFY_Socket.h"

class YFY_Tcp_Socket : public YFY_Socket
{

public:
    YFY_Tcp_Socket();
    YFY_Tcp_Socket(int sockfd);
    ~YFY_Tcp_Socket();
    int recv(void *buff, unsigned int nbytes, int flags, YFY_Time_Value *timeout = 0);
    int send(const void *buff, unsigned int nbytes, int flags);
    int readv(const struct iovec *iov, int iovcnt , YFY_Time_Value *timeout = 0);
    int writev(const struct iovec *iov, int iovcnt);
    int recvMsg(struct msghdr * msg, int flags, YFY_Time_Value *timeout = 0);
    int sendMsg(struct msghdr * msg, int flags);
};
#endif
#include "../inc/YFY_Tcp_Socket.h"

YFY_Tcp_Socket::YFY_Tcp_Socket()
{
    _sockfd = socket(AF_INET, SOCK_STREAM, 0);
}

YFY_Tcp_Socket:: YFY_Tcp_Socket(int sockfd)
{
    setFileDescriptor(sockfd);
}

YFY_Tcp_Socket::~YFY_Tcp_Socket()
{
}

int YFY_Tcp_Socket::recv(void *buff, unsigned int nbytes, int flags, YFY_Time_Value *timeout/* = 0*/)
{
    int sockfd;
    int retval;
    socklen_t len;
    fd_set rset;
    struct timeval tvalue;

    sockfd = _sockfd;
    if(!timeout)
        return  ::recv(sockfd, buff, nbytes, flags);
	
    else
    {
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
		
        tvalue.tv_sec = timeout->getSec();
        tvalue.tv_usec = timeout->getUsec();

        retval= select(sockfd + 1, &rset, NULL, NULL, &tvalue);
        if (retval == -1)
            return -1;
        else if (retval)
        {
            if(FD_ISSET(sockfd, &rset))
                return ::recv(sockfd, buff, nbytes, flags);
            else
                return 0;
        }
        else
            return 0;
    }
}

int YFY_Tcp_Socket::send(const void * buff, unsigned int nbytes, int flags)
{
    return ::send(_sockfd, buff, nbytes, flags);
}

int YFY_Tcp_Socket::readv(const struct iovec * iov, int iovcnt, YFY_Time_Value *timeout/* = 0*/)
{
    int sockfd;
    int retval;
    socklen_t len;
    fd_set rset;
    struct timeval tvalue;

    sockfd = _sockfd;
    if(!timeout)
        return ::readv(sockfd, iov, iovcnt);
	
    else
    {
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
		
        tvalue.tv_sec = timeout->getSec();
        tvalue.tv_usec = timeout->getUsec();

        retval= select(sockfd + 1, &rset, NULL, NULL, &tvalue);
        if (retval == -1)
            return -1;
        else if (retval)
        {
            if(FD_ISSET(sockfd, &rset))
                return  ::readv(sockfd, iov, iovcnt);
            else
                return 0;
        }
        else
            return 0;
    }
}

int YFY_Tcp_Socket::writev(const struct iovec * iov, int iovcnt)
{
    return ::writev(_sockfd, iov, iovcnt);
}

int YFY_Tcp_Socket::recvMsg(struct msghdr * msg, int flags, YFY_Time_Value *timeout/* = 0*/)
{
    int sockfd;
    int retval;
    socklen_t len;
    fd_set rset;
    struct timeval tvalue;

    sockfd = _sockfd;
    if(!timeout)
        return ::recvmsg(sockfd, msg,flags);
    else
    {
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
		
        tvalue.tv_sec = timeout->getSec();
        tvalue.tv_usec = timeout->getUsec();

        retval= select(sockfd + 1, &rset, NULL, NULL, &tvalue);
        if (retval == -1)
            return -1;
        else if (retval)
        {
            if(FD_ISSET(sockfd, &rset))
                return  ::recvmsg(sockfd, msg,flags);
            else
                return 0;
        }
        else
            return 0;
    }
}

int YFY_Tcp_Socket::sendMsg(struct msghdr * msg, int flags)
{
    return ::sendmsg(_sockfd, msg, flags);
}
#ifndef _YFY_UDP_SOCKET_H
#define _YFY_UDP_SOCKET_H

#include "YFY_Socket.h"
#include "YFY_Time_Value.h"
#include "YFY_Addr.h"

class YFY_Udp_Socket:public YFY_Socket
{
public:
    YFY_Udp_Socket();
    ~YFY_Udp_Socket();
    int readv(const struct iovec *iov, int iovcnt , YFY_Time_Value *timeout = 0);
    int writev(const struct iovec *iov, int iovcnt);
    int recvFrom(void *buf, size_t len, int flags, YFY_Addr *src_addr);
    int sendTo(const void *buf, size_t len, int flags, YFY_Addr *dest_addr);
};
#endif
#include "../inc/YFY_Udp_Socket.h"

YFY_Udp_Socket::YFY_Udp_Socket()
{
}

YFY_Udp_Socket::~YFY_Udp_Socket()
{
}

int YFY_Udp_Socket::readv(const struct iovec *iov, int iovcnt , YFY_Time_Value *timeout/* = 0*/)
{
    int sockfd;
    int retval;
    socklen_t len;
    fd_set rset;
    struct timeval tvalue;

    sockfd = _sockfd;
    if(!timeout)
        return ::readv(sockfd, iov, iovcnt);
	
    else
    {
        FD_ZERO(&rset);
        FD_SET(sockfd, &rset);
		
        tvalue.tv_sec = timeout->getSec();
        tvalue.tv_usec = timeout->getUsec();

        retval= select(sockfd + 1, &rset, NULL, NULL, &tvalue);
        if (retval == -1)
            return -1;
        else if (retval)
        {
            if(FD_ISSET(sockfd, &rset))
                return  ::readv(sockfd, iov, iovcnt);
            else
                return 0;
        }
        else
            return 0;
    }
}

int YFY_Udp_Socket::writev(const struct iovec * iov, int iovcnt)
{
    return ::writev(YFY_Socket::_sockfd, iov, iovcnt);
}

int YFY_Udp_Socket::recvFrom(void *buf, size_t len, int flags, YFY_Addr *src_addr)
{
    unsigned int addrlen = src_addr->getSize();
    return ::recvfrom(_sockfd, buf, len, flags, src_addr->convert(), &addrlen);
}

int YFY_Udp_Socket::sendTo(const void *buf, size_t len, int flags, YFY_Addr *dest_addr)
{
    return ::sendto(_sockfd, buf, len, flags, dest_addr->convert(), dest_addr->getSize());
}
#ifndef _YFY_TIME_VALUE_H
#define _YFY_TIME_VALUE_H

class YFY_Time_Value
{
public:
    YFY_Time_Value(unsigned int sec = 0, unsigned int usec = 0);
    ~YFY_Time_Value();
    unsigned int getSec();
    unsigned int getUsec();
    void setSec(unsigned int sec);
    void setUsec(unsigned int usec);
	
public:
    unsigned int _sec;
    unsigned int _usec;
};
#endif
#include "../inc/YFY_Time_Value.h"

YFY_Time_Value::YFY_Time_Value(unsigned int sec/* = 0*/, unsigned int usec/* = 0*/)
{
    _sec = sec;
    _usec = usec;
}

YFY_Time_Value::~YFY_Time_Value()
{
}

unsigned int YFY_Time_Value::getSec()
{
    return _sec;
}

unsigned int YFY_Time_Value::getUsec()
{
    return _usec;
}

void YFY_Time_Value::setSec(unsigned int sec)
{
    _sec = sec;
}

void YFY_Time_Value::setUsec(unsigned int usec)
{
    _usec = usec;
}

#include "YFY_Client.h"
#include <stdio.h>

int main(int argc, char * argv[])
{
    YFY_Tcp_Socket peer;
    YFY_Sock_Connector connector;
    YFY_Addr peer_addr;
    char message[200];
    int n;

    peer_addr.setIp("hostname");
    peer_addr.setPort(DEFAULT_PORT);

    if(0 == connector.connect(peer_addr, peer))
    {
        n = peer.recv(message, 200,  0);
        printf("%s\n", message);
        peer.send("my name is YFY_Client", strlen("my name is YFY_Client"),  0);
        peer.close();
    }
}
#include "YFY_Server.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
    YFY_Addr server_addr;
    YFY_Sock_Acceptor acceptor;
    YFY_Tcp_Socket *peer;
    YFY_Tcp_Socket serv_sock;
    char message[200];
    int optval = 1;
    int optlen = sizeof(optval);

    server_addr.setIp("hostname");
    server_addr.setPort(DEFAULT_PORT);

    serv_sock.setOption(SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
    acceptor.setSocket(&serv_sock);
	
    if(acceptor.open(&server_addr))
    {
        printf("bind or listen error\n");
        return 0;
    }
    if(peer = acceptor.accept())
    {
        peer->send("welcome to server", strlen("welcome to server"),  0);
        peer->recv(message, 200,  0);
        peer->close();
    }
}
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值