Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/output/src/libraries/network/ClientConnection.cc @ 9206

Last change on this file since 9206 was 8807, checked in by landauf, 13 years ago

Replaced COUT with orxout in network library. Tried to set levels and contexts in a more or less useful way, but not really optimized. Used contexts network, packets, and master_server.
Please use endl instead of \n in the future (@smerkli) ;)

  • Property svn:eol-style set to native
File size: 5.8 KB
RevLine 
[1502]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
[3084]23 *      Oliver Scheuss
[1502]24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ClientConnection.h"
30
[3214]31#include <cassert>
[5749]32#define WIN32_LEAN_AND_MEAN
[2773]33#include <enet/enet.h>
[8788]34#include "util/Output.h"
[1502]35
[2171]36namespace orxonox
[1502]37{
[3214]38  const unsigned int NETWORK_CLIENT_WAIT_TIME = 1;
39  const unsigned int NETWORK_CLIENT_CONNECTION_TIMEOUT = 3000; //millisecs
[5965]40  const unsigned int NETWORK_CLIENT_MAX_CONNECTIONS = 1;
[1502]41
42
[3214]43  ClientConnection::ClientConnection():
[8327]44    Connection(NETWORK_PEER_ID_SERVER),
[3214]45    established_(false),
46    server_(NULL)
47  {
48    this->serverAddress_ = new ENetAddress();
49    //set standard address and port
[7459]50    enet_address_set_host(this->serverAddress_, "127.0.0.1"); // TODO: check for IPv6 and connect to ::1 instead
[3214]51    serverAddress_->port = NETWORK_PORT;
[1502]52  }
53
[1907]54  ClientConnection::~ClientConnection(){
[3214]55    if(this->established_)
[1907]56      closeConnection();
[3214]57    delete this->serverAddress_; // surely was created
[1502]58  }
59
[3214]60  void ClientConnection::setServerAddress( const std::string& serverAddress ) {
[7459]61    if (enet_address_set_host (this->serverAddress_, serverAddress.c_str()) < 0)
[8807]62        orxout(internal_error, context::network) << "Could not resolve \"" << serverAddress << "\"." << endl;
[1502]63  }
64
[3214]65  void ClientConnection::setPort( unsigned int port ) {
66    this->serverAddress_->port = port;
[1502]67  }
68
[3214]69  bool ClientConnection::establishConnection()
70  {
71    ENetEvent event;
[6417]72
[7801]73    // create host
74    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, NETWORK_CHANNEL_COUNT, 0, 0);
75   
[3214]76    if ( this->host_ == NULL )
77    {
[8807]78      orxout(internal_error, context::network) << "ClientConnection: host_ == NULL" << endl;
[3214]79      // error handling
[1502]80      return false;
[3214]81    }
[7801]82   
83    // enable compression
84    this->enableCompression();
85   
[7459]86    assert( this->host_->socket4 != ENET_SOCKET_NULL || this->host_->socket6 != ENET_SOCKET_NULL );
87    if (this->host_->socket4 == ENET_SOCKET_NULL)
[8807]88        orxout(internal_warning, context::network) << "IPv4 Socket failed." << endl;
[7459]89    else if (this->host_->socket6 == ENET_SOCKET_NULL)
[8807]90        orxout(internal_warning, context::network) << "IPv6 Socket failed." << endl;
[7459]91    else
[8807]92        orxout(internal_info, context::network) << "Using IPv4 and IPv6 Sockets." << endl;
[7459]93
[7801]94    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CHANNEL_COUNT, 0);
[3214]95    if ( this->server_==NULL )
96    {
[8807]97      orxout(internal_error, context::network) << "ClientConnection: server_ == NULL" << endl;
[3214]98      // error handling
[1502]99      return false;
100    }
[3214]101    // handshake
102    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++ )
[1502]103    {
[3214]104      if( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && event.type == ENET_EVENT_TYPE_CONNECT )
[1502]105      {
[8327]106        // manually add server to list of peers
107        /*incomingEvent inEvent = */Connection::preprocessConnectEvent(event);
108//         addPeer(inEvent.peerID);
109        // start communication thread
[3214]110        this->established_=true;
[7801]111        Connection::startCommunicationThread();
[3214]112        return true;
[1502]113      }
114    }
[8807]115    orxout(user_error, context::network) << "Could not connect to server" << endl;
[3214]116    return false;
[1502]117  }
118
[3214]119  bool ClientConnection::closeConnection() {
[1502]120    ENetEvent event;
[6417]121
[3214]122    if ( !this->established_ )
[3084]123      return true;
[3214]124    this->established_ = false;
[8327]125   
126    // stop communication thread and disconnect server
[7801]127    Connection::stopCommunicationThread();
[3214]128    enet_peer_disconnect(this->server_, 0);
129    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++)
130    {
131      if ( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME) >= 0 )
[1502]132      {
[3214]133        switch (event.type)
134        {
135          case ENET_EVENT_TYPE_NONE:
136          case ENET_EVENT_TYPE_CONNECT:
137            break;
138          case ENET_EVENT_TYPE_RECEIVE:
139            enet_packet_destroy(event.packet);
140            break;
141          case ENET_EVENT_TYPE_DISCONNECT:
[8807]142            orxout(verbose, context::network) << "received disconnect confirmation from server" << endl;
[5929]143            this->connectionClosed();
[3214]144            return true;
145        }
[1502]146      }
147    }
[3214]148    enet_peer_reset( this->server_ );
[5929]149    this->connectionClosed();
[1502]150    return false;
151  }
152
[3214]153
[7801]154  void ClientConnection::addPacket(ENetPacket *packet, uint8_t channelID) {
[3214]155    assert( this->server_ );
156    assert( packet );
[8327]157//     return Connection::addPacket( packet, NETWORK_PEER_ID_SERVER, channelID );
158    // HACK: actually there should be a way to do this using addPacket and the correct peerID
159    return Connection::broadcastPacket(packet, channelID);
[1502]160  }
161
[8327]162  void ClientConnection::addPeer(uint32_t peerID)
[3214]163  {
164    assert(0);
[1502]165  }
[8327]166  void ClientConnection::removePeer(uint32_t peerID)
[3214]167  {
168    this->established_=false;
[8807]169    orxout(internal_error, context::network) << "Received disconnect Packet from Server!" << endl;
[3214]170        // server closed the connection
[7801]171    this->stopCommunicationThread();
[5929]172    this->connectionClosed();
[3214]173  }
[6417]174
[5961]175  uint32_t ClientConnection::getRTT()
[6417]176  {
[7284]177    if (server_)
178        return server_->roundTripTime;
179    else
180        return 0;
[5961]181  }
[1502]182
183}
Note: See TracBrowser for help on using the repository browser.