跨平台支持WindowsSocket网络初始化单例类

xingyun86 2020-8-26 955

跨平台支持WindowsSocket网络初始化单例类

#ifdef _MSC_VER
#include <winsock2.h>
#define PPS_SOCKET SOCKET
#define PPS_SOCKLEN_T int
#define PPS_SOCKOPT_T char
#define PPS_CloseSocket closesocket
#define PPS_SetNonBlock(socketfd,nonblock) u_long nOptVal_##socketfd=(nonblock==0)?0:1;ioctlsocket(socketfd,FIONBIO,&nOptVal_##socketfd)
#define PPS_INVALID_SOCKET INVALID_SOCKET
#define PPS_SOCKET_ERROR SOCKET_ERROR
#define PPS_EWOULDBLOCK WSAEWOULDBLOCK
#define PPS_EINPROGRESS WSAEINPROGRESS
#else
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#define PPS_SOCKET int
#define PPS_SOCKLEN_T socklen_t
#define PPS_SOCKOPT_T void
#define PPS_CloseSocket close
#define PPS_SetNonBlock(socketfd,nonblock) int nOptVal_##socketfd=(nonblock==0)?(fcntl(socketfd,F_GETFL,0)&(~O_NONBLOCK)):(fcntl(socketfd,F_GETFL,0)|(O_NONBLOCK));fcntl(socketfd,F_SETFL,&nOptVal_##socketfd)
#define PPS_INVALID_SOCKET -1
#define PPS_SOCKET_ERROR -1
#define PPS_EWOULDBLOCK EINPROGRESS
#define PPS_EINPROGRESS EINPROGRESS
#endif
class WindowSocket {
#define NET_INIT()       WindowSocket::Init()
#define NET_ERR_CODE     WindowSocket::ErrorCode()
#define NET_ERR_STR(err) WindowSocket::ErrorString(err)
public:
#ifdef _MSC_VER
    WORD wHVer = 0x02;
    WORD wLVer = 0x02;
    WSADATA wsadata = { 0 };
    bool bInitializeSuccessful = false;
#endif // _MSC_VER
    WindowSocket() {
#ifdef _MSC_VER
        // Confirm that the WinSock DLL supports 2.2. Note that if the DLL 
        // supports versions greater than 2.2 in addition to 2.2, it will 
        // still return 2.2 in wVersion since that is the version we requested.        
        if ((WSAStartup(MAKEWORD(wLVer, wHVer), &wsadata) != 0) ||
            (LOBYTE(wsadata.wVersion) != wLVer || HIBYTE(wsadata.wVersion) != wHVer))
        {
            WSACleanup();
            //Tell the user that we could not find a usable WinSock DLL. 
            bInitializeSuccessful = false;
        }
        else
        {
            bInitializeSuccessful = true;
        }
#endif
    }
    ~WindowSocket() {
#ifdef _MSC_VER
        WSACleanup();
#endif
    }
    static std::string ErrorString(unsigned long nErrorCode)
    {
        // Retrieve the system error message for the last-error code
        std::string err("");
#ifdef _MSC_VER
        LPVOID lpMsgBuf = NULL;
        LPVOID lpDisplayBuf = NULL;
        FormatMessageA(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            nErrorCode,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPSTR)&lpMsgBuf,
            0, NULL);
        if (lpMsgBuf != NULL)
        {
            // Display the error message and exit the process
            err.assign((LPCTSTR)lpMsgBuf, strlen((LPCTSTR)lpMsgBuf));
            LocalFree(lpMsgBuf);
            lpMsgBuf = NULL;
        }
#else
        err = strerror(nErrorCode);
#endif // _MSC_VER
        return err;
    }
    static unsigned long ErrorCode()
    {
#ifdef _MSC_VER
        return WSAGetLastError();
#else
        return errno;
#endif // _MSC_VER
    }
    // Return parameter: false-init failure,true-init success
    static bool Init() {
#ifdef _MSC_VER
        static WindowSocket windowSocket;
        return windowSocket.bInitializeSuccessful;
#else
        return true;
#endif
    };
};

调用方法:

int main(int argc, char ** argv)
{
    bool bRet = WindowSocket::Init();
    printf("%s\n", bRet ? "Ok":"FAIL");
    return 0;
}


×
打赏作者
最新回复 (0)
只看楼主
全部楼主
返回