/** * cf_socket.c */ #include "cf_socket.h" #include "cf_local.h" #ifdef _WIN32 # include #else # include # include # include # include # include #endif #include #define CHECK_SOCKET_INIT() \ if (!CF_Socket_IsInitialized ()) \ return CF_ERROR_SOCKET_NOT_INITIALIZED #define CHECK_INVALID_SOCKET(__sock) \ if (__sock < 0) \ return CF_ERROR_SOCKET_INVALID_SOCKET E_CF_BOOL gInitialized = CF_FALSE; E_CF_BOOL CF_Socket_IsInitialized (void) { return gInitialized; } int CF_Socket_Initialize (void) { int result = 0; #ifdef WIN32 WSADATA winsockData; result = WSAStartup (MAKEWORD (2, 0), &winsockData); #endif gInitialized = CF_TRUE; if (result != 0) return CF_ERROR_SOCKET_INITIALIZE; return CF_OK; } int CF_Socket_Finalize (void) { int result = 0; if (!CF_Socket_IsInitialized ()) return CF_ERROR_SOCKET_NOT_INITIALIZED; #ifdef WIN32 result = WSACleanup (); #endif if (result != 0) return CF_ERROR_SOCKET_FINALIZE; return CF_OK; } int CF_Socket_Close (const int sock) { int result = 0; CHECK_INVALID_SOCKET (sock); result = /* continued */ #ifdef _WIN32 closesocket (socket); #else close (sock); #endif if (result != 0) return CF_ERROR_SOCKET_CLOSE; return CF_OK; } int CF_Socket_SetOption (const int sock, const int optname, const void * optval, const size_t optlen) { int result = 0; CHECK_INVALID_SOCKET (sock); result = setsockopt (sock, SOL_SOCKET, optname, #ifdef _WIN32 (char *) optval, #else optval, #endif (socklen_t) optlen); if (result < 0) return CF_ERROR_SOCKET_SET_OPTION; return CF_OK; } int CF_Socket_GetOption (const int sock, const int optname, void * optval, size_t * optlen) { int result = 0; CHECK_INVALID_SOCKET (sock); result = getsockopt (sock, SOL_SOCKET, optname, #ifdef _WIN32 (char *) optval, #else optval, #endif (socklen_t *) optlen); if (result < 0) return CF_ERROR_SOCKET_GET_OPTION; return CF_OK; } int CF_Socket_SetTimeout (const int sock, const int timeout) { int result = 0; CHECK_INVALID_SOCKET (sock); if (timeout < 0) return CF_ERROR_SOCKET_INVALID_ARGS; #ifndef _WIN32 struct timeval timeval; timeval.tv_sec = timeout; timeval.tv_usec= 0; #else int time_ms = timeout * 1000; #endif result = CF_Socket_SetOption (sock, SO_RCVTIMEO, #ifdef _WIN32 &time_ms, sizeof (time_ms)); #else &timeval, sizeof (timeval)); #endif if (result < 0) return CF_ERROR_SOCKET_SET_TIMEOUT; /*----------------------------------------------------------------*/ return CF_OK; } int CF_Socket_Connect (const char * ip, const unsigned short port) { int result = 0; int sock = 0; struct sockaddr_in address; struct hostent * hostEnt; CHECK_SOCKET_INIT (); sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) return CF_ERROR_SOCKET_CREATE; address.sin_family = AF_INET; address.sin_port = htons (port); address.sin_addr.s_addr = inet_addr (ip); TRY { if (address.sin_addr.s_addr == (unsigned int)-1) { hostEnt = gethostbyname (ip); if (hostEnt == NULL) { result = CF_ERROR_SOCKET_GET_HOST; TRY_BREAK; } address.sin_family = (sa_family_t) hostEnt->h_addrtype; memcpy (&(address.sin_addr.s_addr), hostEnt->h_addr, (size_t) hostEnt->h_length); } result = connect (sock, (struct sockaddr *) &address, sizeof (address)); if (result < 0) { result = CF_ERROR_SOCKET_CONNECT; TRY_BREAK; } } CATCH_IF (result < 0) { CF_Socket_Close (sock); return result; } return CF_OK; } int CF_Socket_Server (const unsigned short port, const int backlog) { int result = 0; int sock = 0; struct sockaddr_in address; CHECK_SOCKET_INIT (); sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) return CF_ERROR_SOCKET_CREATE; address.sin_family = AF_INET; address.sin_addr.s_addr = htonl (INADDR_ANY); address.sin_port = htons (port); TRY { result = bind (sock, (struct sockaddr *) &address, sizeof (struct sockaddr)); if (result < 0) { result = CF_ERROR_SOCKET_BIND; TRY_BREAK; } result = listen (sock, backlog); if (result < 0) { result = CF_ERROR_SOCKET_LISTEN; TRY_BREAK; } } CATCH_IF (result < 0) { CF_Socket_Close (sock); return result; } return sock; } int CF_Socket_Accept (const int sock, void * address) { int sockClient; struct sockaddr_in remoteAddress; socklen_t len = sizeof (remoteAddress); CHECK_INVALID_SOCKET (sock); sockClient = accept (sock, (struct sockaddr *) &remoteAddress, &len); if (sockClient < 0) return CF_ERROR_SOCKET_ACCEPT; if (address != NULL) memcpy ((void *) address, (void *) &remoteAddress, sizeof (struct sockaddr_in)); return sockClient; } int CF_Socket_Send (const int sock, const void * buf, const int len) { int result = 0; CHECK_INVALID_SOCKET (sock); result = (int) send (sock, buf, (size_t) len, 0); if (result != len) return CF_ERROR_SOCKET_SEND; return CF_OK; } int CF_Socket_Recv (const int sock, void * buf, const int len) { int result = 0; CHECK_INVALID_SOCKET (sock); result = (int) recv (sock, buf, (size_t) len, 0); if (result < 0) return CF_ERROR_SOCKET_RECV; return result; }