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
Line 
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:
23 *      Oliver Scheuss
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ClientConnection.h"
30
31#include <cassert>
32#define WIN32_LEAN_AND_MEAN
33#include <enet/enet.h>
34#include "util/Output.h"
35
36namespace orxonox
37{
38  const unsigned int NETWORK_CLIENT_WAIT_TIME = 1;
39  const unsigned int NETWORK_CLIENT_CONNECTION_TIMEOUT = 3000; //millisecs
40  const unsigned int NETWORK_CLIENT_MAX_CONNECTIONS = 1;
41
42
43  ClientConnection::ClientConnection():
44    Connection(NETWORK_PEER_ID_SERVER),
45    established_(false),
46    server_(NULL)
47  {
48    this->serverAddress_ = new ENetAddress();
49    //set standard address and port
50    enet_address_set_host(this->serverAddress_, "127.0.0.1"); // TODO: check for IPv6 and connect to ::1 instead
51    serverAddress_->port = NETWORK_PORT;
52  }
53
54  ClientConnection::~ClientConnection(){
55    if(this->established_)
56      closeConnection();
57    delete this->serverAddress_; // surely was created
58  }
59
60  void ClientConnection::setServerAddress( const std::string& serverAddress ) {
61    if (enet_address_set_host (this->serverAddress_, serverAddress.c_str()) < 0)
62        orxout(internal_error, context::network) << "Could not resolve \"" << serverAddress << "\"." << endl;
63  }
64
65  void ClientConnection::setPort( unsigned int port ) {
66    this->serverAddress_->port = port;
67  }
68
69  bool ClientConnection::establishConnection()
70  {
71    ENetEvent event;
72
73    // create host
74    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, NETWORK_CHANNEL_COUNT, 0, 0);
75   
76    if ( this->host_ == NULL )
77    {
78      orxout(internal_error, context::network) << "ClientConnection: host_ == NULL" << endl;
79      // error handling
80      return false;
81    }
82   
83    // enable compression
84    this->enableCompression();
85   
86    assert( this->host_->socket4 != ENET_SOCKET_NULL || this->host_->socket6 != ENET_SOCKET_NULL );
87    if (this->host_->socket4 == ENET_SOCKET_NULL)
88        orxout(internal_warning, context::network) << "IPv4 Socket failed." << endl;
89    else if (this->host_->socket6 == ENET_SOCKET_NULL)
90        orxout(internal_warning, context::network) << "IPv6 Socket failed." << endl;
91    else
92        orxout(internal_info, context::network) << "Using IPv4 and IPv6 Sockets." << endl;
93
94    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CHANNEL_COUNT, 0);
95    if ( this->server_==NULL )
96    {
97      orxout(internal_error, context::network) << "ClientConnection: server_ == NULL" << endl;
98      // error handling
99      return false;
100    }
101    // handshake
102    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++ )
103    {
104      if( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && event.type == ENET_EVENT_TYPE_CONNECT )
105      {
106        // manually add server to list of peers
107        /*incomingEvent inEvent = */Connection::preprocessConnectEvent(event);
108//         addPeer(inEvent.peerID);
109        // start communication thread
110        this->established_=true;
111        Connection::startCommunicationThread();
112        return true;
113      }
114    }
115    orxout(user_error, context::network) << "Could not connect to server" << endl;
116    return false;
117  }
118
119  bool ClientConnection::closeConnection() {
120    ENetEvent event;
121
122    if ( !this->established_ )
123      return true;
124    this->established_ = false;
125   
126    // stop communication thread and disconnect server
127    Connection::stopCommunicationThread();
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 )
132      {
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:
142            orxout(verbose, context::network) << "received disconnect confirmation from server" << endl;
143            this->connectionClosed();
144            return true;
145        }
146      }
147    }
148    enet_peer_reset( this->server_ );
149    this->connectionClosed();
150    return false;
151  }
152
153
154  void ClientConnection::addPacket(ENetPacket *packet, uint8_t channelID) {
155    assert( this->server_ );
156    assert( packet );
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);
160  }
161
162  void ClientConnection::addPeer(uint32_t peerID)
163  {
164    assert(0);
165  }
166  void ClientConnection::removePeer(uint32_t peerID)
167  {
168    this->established_=false;
169    orxout(internal_error, context::network) << "Received disconnect Packet from Server!" << endl;
170        // server closed the connection
171    this->stopCommunicationThread();
172    this->connectionClosed();
173  }
174
175  uint32_t ClientConnection::getRTT()
176  {
177    if (server_)
178        return server_->roundTripTime;
179    else
180        return 0;
181  }
182
183}
Note: See TracBrowser for help on using the repository browser.