跨平台Socket封装

时间:2021-04-02 23:58:24


odsocket.h:

/*
 * define file about portable socketclass.
 * description:this sock is suit bothwindows and linux
 * design:odison
 * e-mail:odison@126.com>
 *
 */

#ifndef _ODSOCKET_H_
#define _ODSOCKET_H_

#ifdef WIN32
        #include<winsock.h>
        typedefint                                socklen_t;
#else
        #include<sys/socket.h>
        #include <netinet/in.h>
        #include<netdb.h>
        #include<fcntl.h>
        #include <unistd.h>
        #include<sys/stat.h>
        #include<sys/types.h>
        #include<arpa/inet.h>
        typedefint                                SOCKET;

        //#pragma region define win32const variable inlinux
        #defineINVALID_SOCKET        -1
        #defineSOCKET_ERROR        -1
        //#pragmaendregion
#endif


class ODSocket {

public:
        ODSocket(SOCKET sock =INVALID_SOCKET);
        ~ODSocket();

        // Create socket object forsnd/recv data
        bool Create(int af, int type,int protocol =0);

        // Connectsocket
        bool Connect(const char* ip,unsigned shortport);
        #regionserver
        // Bindsocket
        bool Bind(unsigned short port);

        // Listensocket
        bool Listen(int backlog = 5);

        // Accept socket
        bool Accept(ODSocket& s,char* fromip =NULL);
        #endregion
        
        // Sendsocket
        int Send(const char* buf, intlen, int flags =0);

        // Recvsocket
        int Recv(char* buf, int len,int flags =0);
        
        // Closesocket
        int Close();

        // Geterrno
        intGetError();
        
        //#pragma region just forwin32
        // Init winsock DLL
        static intInit();        
        // Clean winsockDLL
        static intClean();
        //#pragmaendregion

        // Domain parse
        static bool DnsParse(constchar* domain, char*ip);

        ODSocket& operator =(SOCKET s);

        operator SOCKET();

protected:
        SOCKETm_sock;

};

#endif

 

odsocket.cpp

/*
 * Source file about portable socketclass.
 *
 * design:odison
 * e-mail:odison@126.com>
 *
 */



#include
#include
#include "odsocket.h"

#ifdef WIN32
        #pragma comment(lib,"wsock32")
#endif


ODSocket::ODSocket(SOCKETsock)
{
        m_sock =sock;
}

ODSocket::~ODSocket()
{
}

int ODSocket::Init()
{
#ifdefWIN32
        /*
        http://msdn.microsoft.com/zh-cn/vstudio/ms741563(en-us,VS.85).aspx

        typedef struct WSAData {
                WORDwVersion;                                                                //winsockversion
                WORDwHighVersion;                                                        //Thehighest version of the Windows Sockets specification that the Ws2_32.dll cansupport
                charszDescription[WSADESCRIPTION_LEN+1];
                charszSystemStatus[WSASYSSTATUS_LEN+1];
                unsignedshort iMaxSockets;
                unsignedshort iMaxUdpDg;
                charFAR * lpVendorInfo;
        }WSADATA, *LPWSADATA;
        */
        WSADATAwsaData;
        //#define MAKEWORD(a,b) ((WORD)(((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8))
        WORD version = MAKEWORD(2,0);
        int ret = WSAStartup(version,&wsaData);//win sock startup
        if ( ret ){
                cerr<< "Initilize winsock error !" <<endl;
                return-1;
        }
#endif
        
        return 0;
}
//this is just for windows
int ODSocket::Clean()
{
#ifdef WIN32
                return(WSACleanup());
#endif
                return0;
}

ODSocket& ODSocket::operator = (SOCKETs)
{
        m_sock =s;
        return(*this);
}

ODSocket::operator SOCKET ()
{
        returnm_sock;
}
//create a socket object win/lin is the same
// af:
bool ODSocket::Create(int af, int type, intprotocol)
{
        m_sock = socket(af, type,protocol);
        if ( m_sock == INVALID_SOCKET ){
                returnfalse;
        }
        returntrue;
}

bool ODSocket::Connect(const char* ip, unsigned shortport)
{
        struct sockaddr_insvraddr;
        svraddr.sin_family =AF_INET;
        svraddr.sin_addr.s_addr =inet_addr(ip);
        svraddr.sin_port = htons(port);
        int ret = connect(m_sock,(struct sockaddr*)&svraddr,sizeof(svraddr));
        if ( ret == SOCKET_ERROR ){
                returnfalse;
        }
        returntrue;
}

bool ODSocket::Bind(unsigned short port)
{
        struct sockaddr_insvraddr;
        svraddr.sin_family =AF_INET;
        svraddr.sin_addr.s_addr = INADDR_ANY;
        svraddr.sin_port =htons(port);

        int opt = 1;
        if ( setsockopt(m_sock,SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt)) < 0 )
                returnfalse;

        int ret = bind(m_sock, (structsockaddr*)&svraddr,sizeof(svraddr));
        if ( ret == SOCKET_ERROR ){
                returnfalse;
        }
        return true;
}
//for server
bool ODSocket::Listen(int backlog)
{
        int ret = listen(m_sock,backlog);
        if ( ret == SOCKET_ERROR ){
                returnfalse;
        }
        returntrue;
}

bool ODSocket::Accept(ODSocket& s, char*fromip)
{
        struct sockaddr_incliaddr;
        socklen_t addrlen =sizeof(cliaddr);
        SOCKET sock = accept(m_sock,(struct sockaddr*)&cliaddr, &addrlen);
        if ( sock == SOCKET_ERROR ){
                returnfalse;
        }

        s =sock;
        if ( fromip != NULL)
                sprintf(fromip,"%s",inet_ntoa(cliaddr.sin_addr));

        returntrue;
}

int ODSocket::Send(const char* buf, int len, intflags)
{
        intbytes;
        int count =0;

        while ( count < len ){

                bytes= send(m_sock, buf + count, len - count,flags);
                if( bytes == -1 || bytes == 0 )
                        return-1;
                count+= bytes;
        }

        returncount;
}

int ODSocket::Recv(char* buf, int len, intflags)
{
        return (recv(m_sock, buf, len,flags));
}

int ODSocket::Close()
{
#ifdef WIN32
        return(closesocket(m_sock));
#else
        return (close(m_sock));
#endif
}

int ODSocket::GetError()
{
#ifdef WIN32
        return(WSAGetLastError());
#else
        return (errno);
#endif
}

bool ODSocket::DnsParse(const char* domain, char*ip)
{
        struct hostent*p;
        if ( (p =gethostbyname(domain)) == NULL )
                returnfalse;
                
        sprintf(ip,
                "%u.%u.%u.%u",
                (unsignedchar)p->h_addr_list[0][0],
                (unsignedchar)p->h_addr_list[0][1],
                (unsignedchar)p->h_addr_list[0][2],
                (unsignedchar)p->h_addr_list[0][3]);
        
        return true;
}

 

其实,说是封装,只是简单的把两个类库糅合在一起,主要是为了自己用到的时候可以方便的调用。