#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "cSocket.h" #ifndef _WIN32 #include #include // #include // #include #include //inet_ntoa() #else #define socklen_t int #endif cSocket::cSocket(xSocket a_Socket) : m_Socket(a_Socket) { } cSocket::~cSocket() { } cSocket::operator const cSocket::xSocket() const { return m_Socket; } cSocket::xSocket cSocket::GetSocket() const { return m_Socket; } bool cSocket::IsValid(void) const { #ifdef _WIN32 return (m_Socket != INVALID_SOCKET); #else // _WIN32 return (m_Socket >= 0); #endif // else _WIN32 } void cSocket::CloseSocket() { #ifdef _WIN32 closesocket(m_Socket); #else // _WIN32 if (shutdown(m_Socket, SHUT_RDWR) != 0)//SD_BOTH); { LOGWARN("Error on shutting down socket (%s)", m_IPString.c_str()); } if (close(m_Socket) != 0) { LOGWARN("Error closing socket (%s)", m_IPString.c_str()); } #endif // else _WIN32 // Invalidate the socket so that this object can be re-used for another connection m_Socket = INVALID_SOCKET; } const char * cSocket::GetLastErrorString() { #define CASE_AND_RETURN(x) case x: return #x #ifdef _WIN32 switch (WSAGetLastError()) { CASE_AND_RETURN(WSANOTINITIALISED); CASE_AND_RETURN(WSAENETDOWN); CASE_AND_RETURN(WSAEFAULT); CASE_AND_RETURN(WSAENOTCONN); CASE_AND_RETURN(WSAEINTR); CASE_AND_RETURN(WSAEINPROGRESS); CASE_AND_RETURN(WSAENETRESET); CASE_AND_RETURN(WSAENOTSOCK); CASE_AND_RETURN(WSAEOPNOTSUPP); CASE_AND_RETURN(WSAESHUTDOWN); CASE_AND_RETURN(WSAEWOULDBLOCK); CASE_AND_RETURN(WSAEMSGSIZE); CASE_AND_RETURN(WSAEINVAL); CASE_AND_RETURN(WSAECONNABORTED); CASE_AND_RETURN(WSAETIMEDOUT); CASE_AND_RETURN(WSAECONNRESET); } return "No Error"; #else return "GetLastErrorString() only works on Windows"; #endif } int cSocket::SetReuseAddress() { #ifdef _WIN32 char yes = 1; #else int yes = 1; #endif return setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); } int cSocket::WSAStartup() { #ifdef _WIN32 WSADATA wsaData; memset(&wsaData, 0, sizeof(wsaData)); return ::WSAStartup(MAKEWORD(2, 2),&wsaData); #else return 0; #endif } cSocket cSocket::CreateSocket() { return socket(AF_INET,SOCK_STREAM,0); } int cSocket::Bind(SockAddr_In& a_Address) { sockaddr_in local; if (a_Address.Family == ADDRESS_FAMILY_INTERNET) local.sin_family = AF_INET; if (a_Address.Address == INTERNET_ADDRESS_ANY) local.sin_addr.s_addr = INADDR_ANY; local.sin_port=htons((u_short)a_Address.Port); int res = bind(m_Socket, (sockaddr*)&local, sizeof(local)); if (res != 0) { #ifdef _WIN32 LOGWARNING("bind() failed for port %d, WSAGLE = %d", a_Address.Port, WSAGetLastError()); #else // _WIN32 LOGWARNING("bind() failed for port %d, errno = %d", a_Address.Port, errno); #endif // else _WIN32 } return res; } int cSocket::Listen(int a_Backlog) { return listen(m_Socket, a_Backlog); } cSocket cSocket::Accept() { sockaddr_in from; socklen_t fromlen=sizeof(from); cSocket SClient = accept(m_Socket, (sockaddr*)&from, &fromlen); if (from.sin_addr.s_addr && SClient.IsValid()) // Get IP in string form { SClient.m_IPString = inet_ntoa(from.sin_addr); //LOG("cSocket::Accept() %s", SClient.m_IPString); } return SClient; } int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags) { return recv(m_Socket, a_Buffer, a_Length, a_Flags); }