Created
May 17, 2015 06:51
-
-
Save olevegard/72318ae454aa5db15bd8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ClientTCPConnection - headerphile.com | |
// | |
// This is just as simple wrappaer around TCPsocket,it is meant to be used with NetManager | |
// | |
// It only handles cliwnt connections | |
// ( which means it can only be used to communicate with a server, but not accept incomming connections) | |
// | |
// It can be created by opening a connection to a remote server ( trying to connect to it ) | |
// Or by a server when accepting a new connection. This is the result on the server side after a client tries to connect to it | |
// | |
#pragma once | |
#include <iostream> | |
#include <string> | |
#include <SDL2/SDL_net.h> | |
class ClientTCPConnection | |
{ | |
public: | |
// This is used on the client side. It tries to connect to the server with the ip and port below | |
ClientTCPConnection( const std::string &ip_, int32_t port_ ) | |
{ | |
ip = ip_; | |
port = port_; | |
} | |
// This is used on the server / receiving side. When we accept a connection, we get a TCPsocket in return | |
// We use the below constructor to create a connection from that new TCPsocket | |
ClientTCPConnection( const TCPsocket &conn) | |
{ | |
tcpSocket = conn; | |
} | |
// Initialization | |
// ================================================================ | |
bool SetupIPAddress( ) | |
{ | |
std::cout << "[CLIENT] Resolving host " << ip << " : " << port << std::endl; | |
// Set up the IPAddress struct so that it has the correct IP and port to the server | |
// As stated before, this ONLU sets up the IPaddress. It doesn't try to connect to a server | |
int success = SDLNet_ResolveHost( &ipAddress, ip.c_str(), port ); | |
if ( success == -1 ) | |
{ | |
std::cout << "[CLIENT] Failed to resolve host " << ip << " : " << port << std::endl; | |
return false; | |
} | |
std::cout << "[CLIENT] Host resolved" << std::endl; | |
return true; | |
} | |
bool OpenConnectionToServer( ) | |
{ | |
std::cout << "[CLIENT] Opening connection " | |
<< "\n\tHost name : " << ip << " : " << port | |
<< std::endl; | |
// Try to open the connection to the server. This means the server has to accept the connection | |
// ( Which we do using SDLNet_TCP_Accept) | |
tcpSocket = SDLNet_TCP_Open( &ipAddress ); | |
if ( tcpSocket == nullptr ) | |
{ | |
std::cout << "[CLIENT] Failed to open port " << ip << " : " << port | |
<<" \n\tError : " << SDLNet_GetError() | |
<< std::endl; | |
return false; | |
} | |
std::cout << "[CLIENT] Success!\n"; | |
return true; | |
} | |
void Send( std::string str ) | |
{ | |
// NOTE: Sending data involves a little C style pointer manipulation. | |
// I'll try to find a cleaner, less C-like way to do it. | |
void* messageData = ConvertStringToVoidPtr(str); | |
int messageSize = static_cast< int > ( str.length() ); | |
int bytesSent = bytesSent = SDLNet_TCP_Send( tcpSocket, messageData, messageSize); | |
std::cout << "Trying to send " << str << "\tsent : " << bytesSent << std::endl; | |
if ( bytesSent < messageSize ) | |
{ | |
std::cout << "\tSend failed : " << SDLNet_GetError() << std::endl; | |
} | |
} | |
std::string ReadMessages() | |
{ | |
// If there is no activity, there is no messages for us | |
if ( !CheckForActivity() ) | |
return "[no activity]"; | |
// Allocate a char buffer to hold the message for us | |
char buffer[bufferSize ]; | |
memset( buffer, 0, bufferSize ); | |
// Try to receive data | |
// NOTE: Receiving data involves a little C style pointer manipulation. | |
// I'll try to find a cleaner, less C-like way to do it. | |
int byteCount = SDLNet_TCP_Recv( tcpSocket, buffer, bufferSize ); | |
std::string received(""); | |
std::cout << "Received : " << buffer << "\tCount bytes : " << byteCount << std::endl; | |
// Success! We received something ... | |
if ( byteCount > 0 ) | |
{ | |
// Set the last character to '\0' which means "end of stirng" | |
buffer[byteCount] = '\0'; | |
received = buffer; | |
// If we received more data than our buffer can hold, we will only return the bufferSize first bytes. | |
if ( byteCount >= bufferSize ) | |
std::cout << "[CLIENT] Too much data received : " << byteCount | |
<< "\tbuffer size : " << bufferSize | |
<< "\n\tMaybe increase buffer size?" << std::endl; | |
} | |
// A bytecount of 0 means the connection has been terminated | |
else if ( byteCount == 0 ) | |
{ | |
std::cout << "[CLIENT] Connection terminated : " << std::endl; | |
} | |
// A bytecount of < 0 means an error occured | |
else if ( byteCount < 0 ) | |
{ | |
std::cout << "[CLIENT] Read Failed, terminating connection : " << SDLNet_GetError() << std::endl; | |
} | |
return received; | |
} | |
// Helper functions | |
// ================================================================ | |
// This makes it easy for us to listen to the socket for activity | |
bool CheckForActivity() | |
{ | |
return SDLNet_SocketReady( tcpSocket ) != 0; | |
} | |
// Add the private tcpSocket to a SDLNet_SocketSet | |
void AddToSocketSet( SDLNet_SocketSet* socketSet ) | |
{ | |
SDLNet_TCP_AddSocket( *socketSet, tcpSocket ); | |
} | |
void Close() | |
{ | |
std::cout << "[CLIENT] Closing connection.." << std::endl; | |
SDLNet_TCP_Close( tcpSocket ); | |
} | |
private: | |
// C-style pointer manipulation thingy. Will try to improve this | |
void* ConvertStringToVoidPtr( const std::string &str ) | |
{ | |
const char* charPtr = str.c_str(); | |
return const_cast< char* > ( charPtr ); | |
} | |
std::string ip; | |
int32_t port; | |
int32_t waitTime = 60000; | |
const int bufferSize = 5000; | |
// Holds the adress and port to the server | |
// NOTE: If this object was created via a server connection, it will be null | |
// (which is okay since we just use it to try to connect to the server anyways ) | |
IPaddress ipAddress; | |
TCPsocket tcpSocket; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment