From cf94994f8e3b34bc871e2c3b2558f8301146810c Mon Sep 17 00:00:00 2001 From: faketruth Date: Sun, 23 Oct 2011 00:18:44 +0000 Subject: Abstracted sockets some more to ensure the same behavior over the entire program and on multiple platforms. MCSocket.h should soon be deprecated and deleted Do a full rebuild (mine bugged out when I didn't) git-svn-id: http://mc-server.googlecode.com/svn/trunk@8 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/MCSocket.h | 1 + source/cClientHandle.cpp | 22 ++------- source/cServer.cpp | 82 ++++++++++------------------------ source/cSocket.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++-- source/cSocket.h | 27 ++++++++++- source/cTCPLink.cpp | 8 +--- 6 files changed, 165 insertions(+), 88 deletions(-) (limited to 'source') diff --git a/source/MCSocket.h b/source/MCSocket.h index 6fcbb069b..5dda6c5a3 100644 --- a/source/MCSocket.h +++ b/source/MCSocket.h @@ -1,6 +1,7 @@ #pragma once #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN #include #include // #define socklen_t int diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 68a70715e..d2d71a9e5 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -1,11 +1,3 @@ -#ifndef _WIN32 -#include -#include -#include -#endif - -#include "MCSocket.h" - #include "cClientHandle.h" #include "cServer.h" #include "cWorld.h" @@ -1023,7 +1015,7 @@ void cClientHandle::ReceiveThread( void *lpParam ) while( self->m_bKeepThreadGoing ) { - iStat = recv(socket, &temp, 1, 0); + iStat = socket.Receive( &temp, 1, 0 ); if( cSocket::IsSocketError(iStat) || iStat == 0 ) { LOG("CLIENT DISCONNECTED (%i bytes):%s", iStat, GetWSAError().c_str() ); @@ -1041,11 +1033,7 @@ void cClientHandle::ReceiveThread( void *lpParam ) } else { -#ifndef _WIN32 - LOGERROR("Something went wrong during PacketID 0x%02x (%i)", temp, errno ); -#else - LOGERROR("Something went wrong during PacketID 0x%02x (%s)", temp, GetWSAError().c_str() ); -#endif + LOGERROR("Something went wrong during PacketID 0x%02x (%s)", temp, cSocket::GetLastErrorString() ); LOG("CLIENT %s DISCONNECTED", self->GetUsername() ); break; } @@ -1056,11 +1044,7 @@ void cClientHandle::ReceiveThread( void *lpParam ) char c_Str[128]; -#ifdef _WIN32 - sprintf_s( c_Str, "[C->S] Unknown PacketID: 0x%2x", (unsigned char)temp ); -#else - sprintf( c_Str, "[C->S] Unknown PacketID: 0x%2x", (unsigned char)temp ); -#endif + sprintf_s( c_Str, 128, "[C->S] Unknown PacketID: 0x%2x", (unsigned char)temp ); cPacket_Disconnect DC(c_Str); DC.Send( socket ); diff --git a/source/cServer.cpp b/source/cServer.cpp index a5e06d3ec..511678939 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -29,10 +29,7 @@ #include "packets/cPacket_Chat.h" #ifndef _WIN32 -#include -#include -#include -#include "MCSocket.h" +#define sprintf_s(dst, size, format, ...) sprintf(dst, format, __VA_ARGS__ ) #endif #include @@ -150,64 +147,40 @@ bool cServer::InitServer( int a_Port ) LOG("Starting up server."); -#ifdef _WIN32 - WSADATA wsaData; - memset( &wsaData, 0, sizeof( wsaData ) ); - int wsaret=WSAStartup(/*0x101*/ MAKEWORD(2, 2),&wsaData); - - if(wsaret!=0) + if( cSocket::WSAStartup() != 0 ) // Only does anything on Windows, but whatever { - LOG("wsaret != 0"); + LOGERROR("WSAStartup() != 0"); return false; } -#endif - - sockaddr_in local; - - local.sin_family=AF_INET; - local.sin_addr.s_addr=INADDR_ANY; - local.sin_port=htons((u_short)a_Port); // 25565 - m_pState->SListenClient = socket(AF_INET,SOCK_STREAM,0); + m_pState->SListenClient = cSocket::CreateSocket(); if( !m_pState->SListenClient.IsValid() ) { -#ifdef _WIN32 - LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", GetWSAError().c_str() ); -#else - LOGERROR("m_SListenClient==INVALID_SOCKET"); -#endif + LOGERROR("m_SListenClient==INVALID_SOCKET (%s)", cSocket::GetLastErrorString() ); + return false; } - -#ifdef _WIN32 - char yes = 1; -#else - int yes = 1; -#endif - if (setsockopt( m_pState->SListenClient, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { + if( m_pState->SListenClient.SetReuseAddress() == -1 ) + { LOGERROR("setsockopt == -1"); return false; } - if( bind( m_pState->SListenClient, (sockaddr*)&local, sizeof(local)) != 0 ) + cSocket::SockAddr_In local; + local.Family = cSocket::ADDRESS_FAMILY_INTERNET; + local.Address = cSocket::INTERNET_ADDRESS_ANY; + local.Port = (unsigned short)a_Port; // 25565 + + if( m_pState->SListenClient.Bind( local ) != 0 ) { -#ifdef _WIN32 - LOGERROR("bind fail (%s)", GetWSAError().c_str() ); -#else - LOGERROR("bind fail (%i)", errno); -#endif + LOGERROR("bind fail (%s)", cSocket::GetLastErrorString() ); return false; } - - - if( listen( m_pState->SListenClient , 10 ) != 0) + + if( m_pState->SListenClient.Listen( 10 ) != 0) { -#ifdef _WIN32 - LOGERROR("listen fail (%s)", GetWSAError().c_str() ); -#else - LOGERROR("listen fail (%i)", errno); -#endif + LOGERROR("listen fail (%s)", cSocket::GetLastErrorString() ); return false; } @@ -243,7 +216,7 @@ cServer::cServer() cServer::~cServer() { - if( m_pState->SListenClient ) closesocket( m_pState->SListenClient ); + if( m_pState->SListenClient ) m_pState->SListenClient.CloseSocket(); m_pState->SListenClient = 0; m_pState->bStopListenThread = true; @@ -277,24 +250,17 @@ void cServer::SendAllEntitiesTo(cClientHandle* a_Target) void cServer::StartListenClient() { - sockaddr_in from; - socklen_t fromlen=sizeof(from); - - cSocket SClient = accept( - m_pState->SListenClient, - (sockaddr*)&from, - &fromlen); + cSocket SClient = m_pState->SListenClient.Accept(); - if( from.sin_addr.s_addr && SClient.IsValid() ) + if( SClient.IsValid() ) { - char * ClientIP = 0; - if((ClientIP = inet_ntoa(from.sin_addr)) == 0 ) + char * ClientIP = SClient.GetIPString(); + if( ClientIP == 0 ) return; LOG("%s connected!", ClientIP); - cClientHandle *NewHandle = 0; - NewHandle = new cClientHandle( SClient ); + cClientHandle *NewHandle = new cClientHandle( SClient ); cWorld* World = cRoot::Get()->GetWorld(); World->LockClientHandle(); World->AddClient( NewHandle ); diff --git a/source/cSocket.cpp b/source/cSocket.cpp index edc57c1ce..427441145 100644 --- a/source/cSocket.cpp +++ b/source/cSocket.cpp @@ -1,12 +1,20 @@ #include "cSocket.h" +#include "cMCLogger.h" #ifndef _WIN32 -#include +#include #include +#include +//#include +//#include +#include //inet_ntoa() +#else +#define socklen_t int #endif cSocket::cSocket( xSocket a_Socket ) : m_Socket( a_Socket ) + , m_IPString( 0 ) { } @@ -38,7 +46,106 @@ void cSocket::CloseSocket() #ifdef _WIN32 closesocket(m_Socket); #else - shutdown(m_Socket, SHUT_RDWR);//SD_BOTH); - close(m_Socket); + if( shutdown(m_Socket, SHUT_RDWR) != 0 )//SD_BOTH); + LOGWARN("Error on shutting down socket (%s)", m_IPString ); + if( close(m_Socket) != 0 ) + LOGWARN("Error closing socket (%s)", m_IPString ); #endif +} + +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 ); + + 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); } \ No newline at end of file diff --git a/source/cSocket.h b/source/cSocket.h index cfbc2959f..dde268a8a 100644 --- a/source/cSocket.h +++ b/source/cSocket.h @@ -1,8 +1,8 @@ #pragma once #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN #include -#define socklen_t int #ifdef SendMessage #undef SendMessage #endif @@ -30,6 +30,12 @@ public: xSocket GetSocket() const; void SetSocket( xSocket a_Socket ); + int SetReuseAddress(); + static int WSAStartup(); + + static const char* GetLastErrorString(); + static cSocket CreateSocket(); + inline static bool IsSocketError( int a_ReturnedValue ) { #ifdef _WIN32 @@ -39,7 +45,24 @@ public: #endif } - + struct SockAddr_In + { + short Family; + unsigned short Port; + unsigned long Address; + }; + + static const short ADDRESS_FAMILY_INTERNET = 2; + static const unsigned long INTERNET_ADDRESS_ANY = 0; + + int Bind( SockAddr_In& a_Address ); + int Listen( int a_Backlog ); + cSocket Accept(); + int Receive( char* a_Buffer, unsigned int a_Length, unsigned int a_Flags ); + + char* GetIPString() { return m_IPString; } + private: xSocket m_Socket; + char* m_IPString; }; \ No newline at end of file diff --git a/source/cTCPLink.cpp b/source/cTCPLink.cpp index 0efc0254f..bfd987bd9 100644 --- a/source/cTCPLink.cpp +++ b/source/cTCPLink.cpp @@ -5,10 +5,10 @@ #include "MCSocket.h" #include "cMCLogger.h" +#include #ifndef _WIN32 #include -#include #endif #ifdef _WIN32 @@ -66,11 +66,7 @@ bool cTCPLink::Connect( const char* a_Address, unsigned int a_Port ) #endif m_Socket=socket(AF_INET,SOCK_STREAM,0); -#ifdef _WIN32 - if( m_Socket==INVALID_SOCKET ) -#else - if( m_Socket < 0 ) -#endif + if( !m_Socket.IsValid() ) { LOGERROR("cTCPLink: Invalid socket"); m_Socket = 0; -- cgit v1.2.3