/** * CRXSocket.cpp */ #include "CRXSocket.h" #include #ifdef _WIN32 # pragma comment (lib, "ws2_32.lib") # define close(__socket) closesocket(__socket) #endif bool CRXSocket::mInitialized = false; CRXSocket::CRXSocket (int aSocket) : mSocket (aSocket) { /*----------------------------------------------------------------*/ CRXSocket::Initialize (); memset ((void *)&mAddress, 0x0, sizeof (struct sockaddr_in)); /*----------------------------------------------------------------*/ } CRXSocket::~CRXSocket (void) { /*----------------------------------------------------------------*/ Close (); /*----------------------------------------------------------------*/ } void CRXSocket::Attach (int aSocket) { /*----------------------------------------------------------------*/ mSocket = aSocket; /*----------------------------------------------------------------*/ } int CRXSocket::Detach (void) { int aSocket = mSocket; /*----------------------------------------------------------------*/ mSocket = 0; /*----------------------------------------------------------------*/ return aSocket; } void CRXSocket::Close (void) { /*----------------------------------------------------------------*/ if (mSocket <= 0) return ; close (mSocket); mSocket = 0; /*----------------------------------------------------------------*/ } CRXSocket::operator int (void) const { /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ return mSocket; } CRXSocket & CRXSocket::operator = (int aSocket) { /*----------------------------------------------------------------*/ Attach (aSocket); /*----------------------------------------------------------------*/ return *this; } int CRXSocket::SetTimeout (const int aTimeout) { int aResult = 0; #ifndef _WIN32 struct timeval aTimeVal; aTimeVal.tv_sec = aTimeout; aTimeVal.tv_usec= 0; #else int aTimeMilliSec = aTimeout * 1000; #endif /*----------------------------------------------------------------*/ if (!IsReady ()) return ERROR_TCPSOCKET_NOT_READY; if (aTimeout == TCPSOCKET_NO_TIMEOUT) return 0; aResult = setsockopt (mSocket, SOL_SOCKET, SO_RCVTIMEO, #ifdef _WIN32 (char *) &aTimeMilliSec, #else &aTimeVal, #endif (socklen_t) sizeof (aTimeVal)); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT; CRX_ERROR_SET (aResult, "Failed to set socket option."); } /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::Initialize (void) { int aResult = 0; /*----------------------------------------------------------------*/ if (CRXSocket::IsInitialized ()) return aResult; #ifdef WIN32 WSADATA aWinSockData; aResult = WSAStartup (MAKEWORD (2, 0), &aWinSockData); if (aResult != 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_INITIALIZE; return aResult; } #endif mInitialized = true; /*----------------------------------------------------------------*/ return aResult; } void CRXSocket::Finalize (void) { /*----------------------------------------------------------------*/ #ifdef WIN32 WSACleanup (); #endif /*----------------------------------------------------------------*/ } bool CRXSocket::IsInitialized (void) { /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ return mInitialized; } bool CRXSocket::IsReady (void) const { /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ return IsInitialized () && IsCreated (); } bool CRXSocket::IsCreated (void) const { /*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/ return mSocket > 0 ? true : false; } int CRXSocket::CreateSocket (void) { int aResult = -1; /*----------------------------------------------------------------*/ if (!IsInitialized () || IsCreated ()) { aResult = ERROR_TCPSOCKET_ALREADY_IN_USE; CRX_ERROR_SET (aResult, "Already in use."); return aResult; } aResult = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET; CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ()); return aResult; } mSocket = aResult; /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::Connect (const std::string aUrl, const unsigned short aPort, const int aTimeout) { int aResult = -1; struct hostent * aHostEnt; struct linger aLinger; /*----------------------------------------------------------------*/ aResult = CreateSocket (); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET; CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ()); return aResult; } mAddress.sin_family = AF_INET; mAddress.sin_port = htons (aPort); mAddress.sin_addr.s_addr = inet_addr (aUrl.c_str ()); if (mAddress.sin_addr.s_addr == (unsigned int)-1) { aHostEnt = gethostbyname (aUrl.c_str ()); if (aHostEnt == NULL) { aResult = ERROR_TCPSOCKET_FAILED_TO_GET_HOSTNAME; CRX_ERROR_SET (aResult, "Failed to get hostname."); return aResult; } mAddress.sin_family = aHostEnt->h_addrtype; memcpy (&(mAddress.sin_addr.s_addr), aHostEnt->h_addr, aHostEnt->h_length); } aLinger.l_onoff = 1; aLinger.l_linger = 0; aResult = setsockopt (mSocket, SOL_SOCKET, SO_LINGER, #ifdef _WIN32 (char *) &aLinger, #else &aLinger, #endif (socklen_t) sizeof (aLinger)); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT; CRX_ERROR_SET (aResult, "Failed to set socket option (linger)."); } aResult = SetTimeout (aTimeout); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_SET_TIMEOUT; CRX_ERROR_SET (aResult, "Failed to set timeout (%d).", GetSystemErrorCode ()); return aResult; } aResult = connect (mSocket, (struct sockaddr*) &mAddress, sizeof (mAddress)); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_CONNECT; CRX_ERROR_SET (aResult, "Failed to connect (%d).", GetSystemErrorCode ()); } /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::CreateServer (const unsigned short aPort, const int aBacklog, struct sockaddr_in * aAddress) { int aResult = -1; int aReuseAddress = 1; /*----------------------------------------------------------------*/ aResult = CreateSocket (); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_CREATE_SOCKET; CRX_ERROR_SET (aResult, "Failed to create socket(%d).", GetSystemErrorCode ()); return aResult; } aResult = setsockopt (mSocket, SOL_SOCKET, SO_REUSEADDR, #ifdef _WIN32 (char *) &aReuseAddress, #else &aReuseAddress, #endif (socklen_t) sizeof (aReuseAddress)); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_SET_SOCKOPT; CRX_ERROR_SET (aResult, "Failed to set socket option (reuseaddr)."); } mAddress.sin_family = AF_INET; mAddress.sin_addr.s_addr= htonl (INADDR_ANY); mAddress.sin_port = htons (aPort); aResult = bind (mSocket, (struct sockaddr *)&mAddress, sizeof (struct sockaddr)); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_BIND; CRX_ERROR_SET (aResult, "Failed to bind(%d).", GetSystemErrorCode ()); return aResult; } aResult = listen (mSocket, aBacklog); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_LISTEN; CRX_ERROR_SET (aResult, "Failed to listen(%d).", GetSystemErrorCode ()); return aResult; } if (aAddress != NULL) { memset ((void *)aAddress, 0x0, sizeof (struct sockaddr_in)); memcpy ((void *)aAddress, (void *)&mAddress, sizeof (struct sockaddr_in)); } /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::Accept (struct sockaddr_in * aRemoteAddress, int * aAddressLength) { int aResult = -1; struct sockaddr_in aAddress; socklen_t aLength = sizeof (aAddress); /*----------------------------------------------------------------*/ if (!IsReady ()) return ERROR_TCPSOCKET_NOT_READY; aResult = accept (mSocket, (struct sockaddr *) &aAddress, &aLength); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_ACCEPT; CRX_ERROR_SET (aResult, "Failed to accept(%d).", GetSystemErrorCode ()); return aResult; } if (aRemoteAddress != NULL) { memset ((void *)aRemoteAddress, 0x0, sizeof (struct sockaddr_in)); memcpy ((void *)aRemoteAddress, (void *)&aAddress, sizeof (struct sockaddr_in)); } if (aAddressLength != NULL) *aAddressLength = aLength; /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::Send (const char * aBuffer, int aSize) { int aResult = -1; /*----------------------------------------------------------------*/ if (!IsReady ()) return ERROR_TCPSOCKET_NOT_READY; aResult = send (mSocket, aBuffer, aSize, 0); if (aResult != aSize) { aResult = ERROR_TCPSOCKET_FAILED_TO_SEND; CRX_ERROR_SET (aResult, "Failed to send(%d).", GetSystemErrorCode ()); return aResult; } /*----------------------------------------------------------------*/ return aResult; } int CRXSocket::Receive (char * aBuffer, int aSize) { int aResult = -1; /*----------------------------------------------------------------*/ if (!IsReady ()) return ERROR_TCPSOCKET_NOT_READY; aResult = recv (mSocket, aBuffer, aSize, 0); if (aResult < 0) { aResult = ERROR_TCPSOCKET_FAILED_TO_RECEIVE; CRX_ERROR_SET (aResult, "Failed to receive(%d).", GetSystemErrorCode ()); return aResult; } /*----------------------------------------------------------------*/ return aResult; }