#include "Klient.h" #ifndef WIN32 #include #endif #include #include using namespace Network; // inhalt der Klient Klasse aus Klient.h // Konstruktor Klient::Klient() { memset( &server, 0, sizeof( server ) ); server.sin_family = AF_INET; ref = 1; downStreamBytes = 0; upStreamBytes = 0; sock = 0; sendeKey = 0; empfangKey = 0; } // Destruktoe Klient::~Klient() { if( sock ) trenne(); if( sendeKey ) sendeKey->release(); if( empfangKey ) empfangKey->release(); } // nicht constant void Klient::setSendeKeyZ( Encryption::Key *key ) // Setzt den Key fürs Senden { if( sendeKey ) sendeKey->release(); sendeKey = key; } void Klient::setEmpfangKeyZ( Encryption::Key *key ) // Setzt den Key fürs Empfangen { if( empfangKey ) empfangKey->release(); empfangKey = key; } void Klient::setSendeKey( char *key, int len ) // Setzt den Key fürs Senden { if( !sendeKey ) sendeKey = new Encryption::Key(); sendeKey->setKey( key, len ); } void Klient::setEmpfangKey( char *key, int len ) // Setzt den Key fürs Empfangen { if( !empfangKey ) empfangKey = new Encryption::Key(); empfangKey->setKey( key, len ); } bool Klient::verbinde( unsigned short port, const char *ip ) // verbindet mit Server { if( sendeKey ) sendeKey->setPos( 0 ); if( empfangKey ) empfangKey->setPos( 0 ); if( sock ) closesocket( sock ); sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); long sIp = inet_addr( ip ); // ip addresse memcpy( (char*)&server.sin_addr, &sIp, sizeof( sIp ) ); server.sin_port = htons( port ); // port if( connect( sock, ( struct sockaddr* )&server, sizeof( server ) ) < 0 ) // verbinden return 0; // Fehler return 1; } bool Klient::sende( const char *nachricht, int len ) // sendet zum Server { int ll = 0; while( len > 0 ) { #ifdef WIN32 int l = send( sock, nachricht + ll, len, 0 ); #else int l = (int)send( sock, nachricht + ll, len, MSG_NOSIGNAL ); #endif if( l <= 0 ) return 0; // Fehler len -= l; ll += l; } upStreamBytes += ll; return 1; } bool Klient::getNachricht( char *nachricht, int len ) // empfängt Nachricht { int ll = 0; while( len > 0 ) { int l = (int)recv( sock, nachricht + ll, len, MSG_WAITALL ); if( l <= 0 ) return 0; // Fehler len -= l; ll += l; } downStreamBytes += ll; return 1; } bool Klient::sendeEncrypted( const char *nachricht, int len ) // sendet zum Server { if( !sendeKey ) return sende( nachricht, len ); Encryption::Bytes *n = new Encryption::Bytes( nachricht, len ); sendeKey->codieren( n->getThis() ); int ll = 0; while( len > 0 ) { #ifdef WIN32 int l = send( sock, n->getBytes() + ll, len, 0 ); #else int l = (int)send( sock, n->getBytes() + ll, len, MSG_NOSIGNAL ); #endif if( l <= 0 ) { n->release(); return 0; // Fehler } len -= l; ll += l; } upStreamBytes += ll; n->release(); return 1; } bool Klient::getNachrichtEncrypted( char *nachricht, int len ) // empfängt Nachricht { if( !empfangKey ) return getNachricht( nachricht, len ); int ll = 0; while( len > 0 ) { int l = (int)recv( sock, nachricht + ll, len, MSG_WAITALL ); if( l <= 0 ) return 0; // Fehler len -= l; ll += l; } Encryption::Bytes *n = new Encryption::Bytes(); n->setBytesZ( nachricht, ll ); empfangKey->decodieren( n ); downStreamBytes += ll; return 1; } int Klient::getDownloadBytes( bool reset ) // gibt die anzahl von empfangen bytes zurück { int ret = downStreamBytes; if( reset ) downStreamBytes = 0; return ret; } int Klient::getUploadBytes( bool reset ) // gibt die anzahl von versendeter bytes zurück { int ret = upStreamBytes; if( reset ) upStreamBytes = 0; return ret; } bool Klient::trenne() // Trennt die Verbindung zum Server { if( !sock ) return 1; if( sendeKey ) sendeKey->setPos( 0 ); if( empfangKey ) empfangKey->setPos( 0 ); if( closesocket( sock ) < 0 ) // verbindung Trennen return 0; // Fehler sock = 0; return 1; } // constant bool Klient::hatNachricht( int zeit ) // Wartet eine Zeit Lang auf eine Nachricht { #ifdef WIN32 fd_set set = { 1, { sock } }; timeval time = { zeit / 1000, zeit }; return select( 0, &set, 0, 0, &time ) == 1; #else return 1; #endif } unsigned short Klient::getServerPort() const // gibt den Port zurück { return htons( server.sin_port ); } const char *Klient::getServerIp() const // gibt die Ip zurück { return inet_ntoa( server.sin_addr ); } // Reference Counting Klient *Klient::getThis() { ref++; return this; } Klient *Klient::release() { ref--; if( !ref ) delete this; return 0; }