From 386d58b5862d8b76925c6523721594887606e82a Mon Sep 17 00:00:00 2001 From: faketruth Date: Mon, 3 Oct 2011 18:41:19 +0000 Subject: MCServer c++ source files git-svn-id: http://mc-server.googlecode.com/svn/trunk@3 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cTCPLink.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 source/cTCPLink.cpp (limited to 'source/cTCPLink.cpp') diff --git a/source/cTCPLink.cpp b/source/cTCPLink.cpp new file mode 100644 index 000000000..13eb593ef --- /dev/null +++ b/source/cTCPLink.cpp @@ -0,0 +1,146 @@ +#include "cTCPLink.h" +#include "cSocket.h" +#include "cEvent.h" +#include "cThread.h" + +#include "cMCLogger.h" + +#ifndef _WIN32 +#include +#include +#endif + +#ifdef _WIN32 +#define MSG_NOSIGNAL (0) +#endif +#ifdef __MACH__ +#define MSG_NOSIGNAL (0) +#endif + +cTCPLink::cTCPLink() + : m_Socket( 0 ) + , m_StopEvent( new cEvent() ) +{ +} + +cTCPLink::~cTCPLink() +{ + if( m_Socket ) + { + CloseSocket(); + m_StopEvent->Wait(); + } + delete m_StopEvent; +} + +void cTCPLink::CloseSocket() +{ + if( m_Socket ) + { + closesocket( m_Socket ); + m_Socket = 0; + } +} + +bool cTCPLink::Connect( const char* a_Address, unsigned int a_Port ) +{ + if( m_Socket ) + { + LOGWARN("WARNING: cTCPLink Connect() called while still connected. ALWAYS disconnect before re-connecting!"); + } + + struct hostent *hp; + unsigned int addr; + struct sockaddr_in server; + +#ifdef _WIN32 + WSADATA wsaData; + int wsaret=WSAStartup(/*0x101*/ MAKEWORD(2, 2),&wsaData); + + if(wsaret!=0) + { + LOGERROR("cTCPLink: WSAStartup returned error"); + return false; + } +#endif + + m_Socket=socket(AF_INET,SOCK_STREAM,0); +#ifdef _WIN32 + if( m_Socket==INVALID_SOCKET ) +#else + if( m_Socket < 0 ) +#endif + { + LOGERROR("cTCPLink: Invalid socket"); + m_Socket = 0; + return false; + } + + + addr=inet_addr( a_Address ); + hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); + if(hp==NULL) + { + //LOGWARN("cTCPLink: gethostbyaddr returned NULL"); + hp = gethostbyname( a_Address ); + if( hp == NULL ) + { + LOGWARN("cTCPLink: Could not resolve %s", a_Address); + CloseSocket(); + return false; + } + } + + server.sin_addr.s_addr=*((unsigned long*)hp->h_addr); + server.sin_family=AF_INET; + server.sin_port=htons( (unsigned short)a_Port ); + if( connect( m_Socket, (struct sockaddr*)&server, sizeof(server) ) ) + { + LOGWARN("cTCPLink: No response from server (%i)", errno); + CloseSocket(); + return false; + } + + cThread( ReceiveThread, this ); + + return true; +} + +int cTCPLink::Send( char* a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) +{ + //LOG("TCPLink::Send()"); + if( !m_Socket ) + { + LOGWARN("cTCPLink: Trying to send data without a valid connection!"); + return -1; + } + return send( m_Socket, a_Data, a_Size, a_Flags | MSG_NOSIGNAL ); +} + +int cTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) +{ + //LOG("TCPLink::SendMessage()"); + if( !m_Socket ) + { + LOGWARN("cTCPLink: Trying to send message without a valid connection!"); + return -1; + } + return send( m_Socket, a_Message, strlen(a_Message), a_Flags | MSG_NOSIGNAL ); +} + +void cTCPLink::ReceiveThread( void* a_Param) +{ + cTCPLink* self = (cTCPLink*)a_Param; + SOCKET Socket = self->m_Socket; + int Received = 0; + do + { + char Data[256]; + Received = recv(Socket, Data, 256, 0); + self->ReceivedData( Data, (Received>0?Received:-1) ); + } while ( Received > 0 ); + + LOGINFO("cTCPLink Disconnected (%i)", Received ); + + if( Socket == self->m_Socket ) self->m_StopEvent->Set(); +} -- cgit v1.2.3