跨平台Socket封装——CSocketImpl类

来源:互联网 发布:淘宝店无线端装修 编辑:程序博客网 时间:2024/05/22 08:08

头文件SocketImpl.h

namespace LinWin{    class CSocketImpl    {    private:        net_socket_fd m_sock;        bool          m_bBlocking;    public:        CSocketImpl();        CSocketImpl(net_socket_fd sockfd);        CSocketImpl(const CSocketImpl& iml);        virtual ~CSocketImpl();    public:        virtual int Create(int af = AF_INET, int type = SOCK_STREAM, int proto = 0);        virtual void Close();        virtual int Bind(const CSocketAddress& address);        virtual int Listen(int backlog = 64);        virtual int Accept(CSocketImpl* connfd, CSocketAddress& clientAddr);        virtual int Connect(const CSocketAddress& addr);        virtual int SendBytes(const void* lpBuf, unsigned int lpLen, int flag = 0);        virtual int RecvBytes(void* lpBuf, unsigned int lpLen, int flag = 0);        virtual int SendBytesto(const void* lpBuf, unsigned int lpLen, const CSocketAddress& addr, int flag = 0);        virtual int RecvBytesfrom(void* lpBuf, unsigned int lpLen, CSocketAddress& addr, int flag = 0);        virtual int ShutdownReceive();        virtual int ShutdownSend();        virtual int Shutdown();        virtual int SetSendBufferSize(int size);        virtual int GetSendBufferSize(int& size);        virtual int SetReceiveBufferSize(int size);        virtual int GetReceiveBufferSize(int& size);        virtual int LocalAddress(CSocketAddress& localAddr);        virtual int RemoteAddress(CSocketAddress& remoteAddr);        virtual int Available(int& result);        int SetOption(int level, int option, int value);        int SetOption(int level, int option, unsigned value);        int SetOption(int level, int option, unsigned char value);        virtual int SetRawOption(int level, int option, const void* value, int length);        int GetOption(int level, int option, int& value);        int GetOption(int level, int option, unsigned& value);        int GetOption(int level, int option, unsigned char& value);        virtual int GetRawOption(int level, int option, void* value, int length);        int SetLinger(bool on, int seconds);        int GetLinger(bool& on, int& seconds);        int SetNoDelay(bool flag);        int GetNoDelay(bool& flag);        int SetKeepAlive(bool flag);        int GetKeepAlive(bool& flag);        int SetReuseAddress(bool flag);        int GetReuseAddress(bool& flag);        virtual int SetBlocking(bool flag);        virtual bool GetBlocking() const;        net_socket_fd Sockfd() const;        const net_socket_fd* Handle() const        {            return reinterpret_cast<const net_socket_fd*>(&m_sock);        }        int SocketError();        virtual int Ioctl(net_ioctl_request_t request, int& arg);        virtual int Ioctl(net_ioctl_request_t request, void* arg);    }}

Socket网络编程最基本的操作都封装在这里了,随后再把扩展的加进来。net_socket_fd类型的定义是为了统一平台之间的差异,它的定义已在platform.h文件中更新(在之前博客中)。

SocketImpl.cpp文件

#include "SocketImpl.h"LinWin::CSocketImpl::CSocketImpl() : m_sock(NET_INVALID_SOCKET), m_bBlocking(false){}LinWin::CSocketImpl::CSocketImpl(net_socket_fd sock) : m_sock(sock), m_bBlocking(false){}LinWin::CSocketImpl::CSocketImpl(const CSocketImpl& iml) : m_sock(iml.m_sock), m_bBlocking(iml.m_bBlocking){}LinWin::CSocketImpl::~CSocketImpl(){    Close();}int LinWin::CSocketImpl::Create(int af /* = AF_INET */, int type /* = SOCK_STREAM */, int proto /* = 0 */){    m_sock = ::socket(af, type, proto);    return m_sock == NET_INVALID_SOCKET ? -1 : 0;}void LinWin::CSocketImpl::Close(){    if (m_sock != NET_INVALID_SOCKET)    {        closesocket(m_sock);        m_sock = NET_INVALID_SOCKET;    }}int LinWin::CSocketImpl::Bind(const CSocketAddress& address){    if (m_sock == NET_INVALID_SOCKET)        return -2;    if (::bind(m_sock, reinterpret_cast<const struct sockaddr *>(address.GetAddress()), address.AddressLength()) != 0)        return -1;    return 0;}int LinWin::CSocketImpl::Listen(int backlog /* = 64 */){    if (m_sock == NET_INVALID_SOCKET)        return -2;    if (::listen(m_sock, backlog) != 0)        return -1;    return 0;}int LinWin::CSocketImpl::Accept(CSocketImpl* connfd, CSocketAddress& clientAddr){    if (m_sock == NET_INVALID_SOCKET || connfd == NULL)        return -2;    socklen_t salen = clientAddr.AddressLength();    connfd->m_sock = ::accept(m_sock, reinterpret_cast<struct sockaddr*>(clientAddr.GetAddress()), &salen);    if (connfd->m_sock == NET_INVALID_SOCKET)        return -1;    return 0;}int LinWin::CSocketImpl::Connect(const CSocketAddress& addr){    if (m_sock == NET_INVALID_SOCKET)        return -2;    if (::connect(m_sock, reinterpret_cast<const struct sockaddr *>(addr.GetAddress()), addr.AddressLength()) != 0)        return -1;    return 0;}int LinWin::CSocketImpl::SendBytes(const void* lpBuf, unsigned int lpLen, int flag){    return ::send(m_sock, reinterpret_cast<const char*>(lpBuf), lpLen, flag);}int LinWin::CSocketImpl::RecvBytes(void* lpBuf, unsigned int lpLen, int flag){    return ::recv(m_sock, reinterpret_cast<char*>(lpBuf), lpLen, flag);}int LinWin::CSocketImpl::SendBytesto(const void* lpBuf, unsigned int lpLen, const CSocketAddress& addr, int flag){    return ::sendto(m_sock, reinterpret_cast<const char*>(lpBuf), lpLen, flag,        reinterpret_cast<const struct sockaddr*>(addr.GetAddress()), addr.AddressLength());}int LinWin::CSocketImpl::RecvBytesfrom(void* lpBuf, unsigned int lpLen, CSocketAddress& addr, int flag){    socklen_t addrLen = addr.AddressLength();    return ::recvfrom(m_sock, reinterpret_cast<char*>(lpBuf), lpLen, flag,         reinterpret_cast<sockaddr*>(addr.GetAddress()), &addrLen);}int LinWin::CSocketImpl::ShutdownReceive(){    return (::shutdown(m_sock, SD_RECEIVE) != 0) ? -1 : 0;}int LinWin::CSocketImpl::ShutdownSend(){       return (::shutdown(m_sock, SD_SEND) != 0) ? -1 : 0;}int LinWin::CSocketImpl::Shutdown(){    return (::shutdown(m_sock, SD_BOTH) != 0) ? -1 : 0;}int LinWin::CSocketImpl::SetSendBufferSize(int size){    return SetOption(SOL_SOCKET, SO_SNDBUF, size);}int LinWin::CSocketImpl::GetSendBufferSize(int& size){    return GetOption(SOL_SOCKET, SO_SNDBUF, size);}int LinWin::CSocketImpl::SetReceiveBufferSize(int size){    return SetOption(SOL_SOCKET, SO_RCVBUF, size);}int LinWin::CSocketImpl::GetReceiveBufferSize(int& size){    return GetOption(SOL_SOCKET, SO_RCVBUF, size);}int LinWin::CSocketImpl::LocalAddress(CSocketAddress& localAddr){    socklen_t saLen = sizeof(struct sockaddr_in);    int rc = ::getsockname(m_sock, reinterpret_cast<struct sockaddr*>(localAddr.GetAddress()), &saLen);    return rc != 0 ? -1 : 0;}int LinWin::CSocketImpl::RemoteAddress(CSocketAddress& remoteAddr){    socklen_t saLen = sizeof(struct sockaddr_in);    int rc = ::getpeername(m_sock, reinterpret_cast<struct sockaddr*>(remoteAddr.GetAddress()), &saLen);    return rc != 0 ? -1 : 0;}int LinWin::CSocketImpl::Available(int& result){    return Ioctl(FIONREAD, result);}int LinWin::CSocketImpl::SetOption(int level, int option, int value){    return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetOption(int level, int option, unsigned value){    return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetOption(int level, int option, unsigned char value){    return SetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::SetRawOption(int level, int option, const void* value, int length){    int rc = ::setsockopt(m_sock, level, option, reinterpret_cast<const char*>(value), (socklen_t)length);    return rc == -1 ? -1 : 0;}int LinWin::CSocketImpl::GetOption(int level, int option, int& value){    return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetOption(int level, int option, unsigned& value){    return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetOption(int level, int option, unsigned char& value){    return GetRawOption(level, option, &value, sizeof(value));}int LinWin::CSocketImpl::GetRawOption(int level, int option, void* value, int length){    int rc = ::getsockopt(m_sock, level, option, reinterpret_cast<char*>(value), reinterpret_cast<socklen_t*>(&length));    return rc == -1 ? -1 : 0;}int LinWin::CSocketImpl::SetLinger(bool on, int seconds){    struct linger l;    l.l_onoff = on ? 1 : 0;    l.l_linger = seconds;    return SetRawOption(SOL_SOCKET, SO_LINGER, &l, sizeof(l));}int LinWin::CSocketImpl::GetLinger(bool& on, int& seconds){    struct linger l;    int len = sizeof(l);    int ret = GetRawOption(SOL_SOCKET, SO_LINGER, &l, len);    if (ret == 0)    {        on = (l.l_onoff != 0);        seconds = l.l_linger;    }    return ret;}int LinWin::CSocketImpl::SetNoDelay(bool flag){    int value = flag ? 1 : 0;    return SetOption(IPPROTO_TCP, TCP_NODELAY, value);}int LinWin::CSocketImpl::GetNoDelay(bool& flag){    int value = 0;    int ret = GetOption(IPPROTO_TCP, TCP_NODELAY, value);    if (ret == 0)        flag = (value != 0);    return ret;}int LinWin::CSocketImpl::SetKeepAlive(bool flag){    int value = flag ? 1 : 0;    return SetOption(SOL_SOCKET, SO_KEEPALIVE, value);}int LinWin::CSocketImpl::GetKeepAlive(bool& flag){    int value(0);    int ret = GetOption(SOL_SOCKET, SO_KEEPALIVE, value);    if (ret == 0)        flag = (value != 0);    return ret;}int LinWin::CSocketImpl::SetReuseAddress(bool flag){    int value = flag ? 1 : 0;    return SetOption(SOL_SOCKET, SO_REUSEADDR, value);}int LinWin::CSocketImpl::GetReuseAddress(bool& flag){    int value(0);    int ret = GetOption(SOL_SOCKET, SO_REUSEADDR, value);    if (ret == 0)        flag = (value != 0);    return ret;}int LinWin::CSocketImpl::SetBlocking(bool flag){#ifdef WINDOWS_FAMILY    unsigned long nonblocking = flag ? 1 : 0;    if (ioctlsocket(m_sock, FIONBIO, (unsigned long*)&nonblocking) == SOCKET_ERROR)        return -1;#else    int opts;    opts = fcntl(m_sock, F_GETFL);    if (opts < 0)        return -1;    if (flag)        opts = opts | O_NONBLOCK;    else        opts = opts & (~O_NONBLOCK);    if (fcntl(m_sock, F_SETFL, opts) < 0)        return -1;#endif    m_bBlocking = flag;    return 0;}bool LinWin::CSocketImpl::GetBlocking() const{    return m_bBlocking;}net_socket_fd LinWin::CSocketImpl::Sockfd() const{    return m_sock;}int LinWin::CSocketImpl::Ioctl(net_ioctl_request_t request, int& arg){    int rc;#ifdef WINDOWS_FAMILY    rc = ioctlsocket(m_sock, request, reinterpret_cast<u_long*>(&arg));#else    rc = ::ioctl(m_sock, request, &arg);#endif    return (rc != 0) ? -1 : 0;}int LinWin::CSocketImpl::Ioctl(net_ioctl_request_t request, void* arg){    int rc;#ifdef WINDOWS_FAMILY    rc = ioctlsocket(m_sock, request, reinterpret_cast<u_long*>(arg));#else    rc = ::ioctl(m_sock, request, arg);#endif    return (rc != 0) ? -1 : 0;}int LinWin::CSocketImpl::SocketError(){#ifdef WINDOWS_FAMILY    return GetLastError();#else    return errno;#endif}

由于CSocketAddress类中添加了一个非const版本的GetAddress成员函数,所以去掉此类中所有const_cast的转换。

0 0
原创粉丝点击