ab95abb6bd
Crossplatform GetLastError function in cSocket git-svn-id: http://mc-server.googlecode.com/svn/trunk@234 0a769ca7-a7f5-676a-18bf-c427514a06d6
243 lines
3.7 KiB
C++
243 lines
3.7 KiB
C++
|
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
|
|
|
#include "cSocket.h"
|
|
|
|
#ifndef _WIN32
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
// #include <sys/socket.h>
|
|
// #include <netinet/in.h>
|
|
#include <arpa/inet.h> //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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AString cSocket::GetErrorString( int a_ErrNo )
|
|
{
|
|
#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
|
|
char buffer[ 256 ];
|
|
if( strerror_r( errno, buffer, 256 ) == 0 )
|
|
{
|
|
return AString( buffer );
|
|
}
|
|
else
|
|
{
|
|
return "Error on getting error string!";
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
|
|
int cSocket::GetLastError()
|
|
{
|
|
#ifdef _WIN32
|
|
return WSAGetLastError();
|
|
#else
|
|
return errno;
|
|
#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);
|
|
|
|
return bind(m_Socket, (sockaddr*)&local, sizeof(local));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
|