Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/network/ClientConnection.cc @ 745

Last change on this file since 745 was 742, checked in by landauf, 17 years ago

moved all files from misc and the tinyxml folder into the new util folder

File size: 5.7 KB
RevLine 
[514]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Oliver Scheuss, (C) 2007
23 *   Co-authors:
24 *      ...
25 *
26 */
27
[217]28//
29// C++ Interface: ClientConnection
30//
[285]31// Description: The Class ClientConnection manages the servers conenctions to the clients.
32// each connection is provided by a new process. communication between master process and
[217]33// connection processes is provided by ...
34//
35//
36// Author:  Oliver Scheuss
37//
38
[285]39#include "ClientConnection.h"
[217]40
[742]41#include "util/Sleep.h"
[448]42
[217]43namespace network{
[285]44
[346]45  static boost::thread_group network_threads;
[285]46
[217]47  ClientConnection::ClientConnection(int port, std::string address){
48    quit=false;
49    server=NULL;
50    enet_address_set_host(&serverAddress, address.c_str());
51    serverAddress.port = NETWORK_PORT;
52    established=false;
53  }
[285]54
[217]55  ClientConnection::ClientConnection(int port, const char *address){
56    quit=false;
57    server=NULL;
58    enet_address_set_host(&serverAddress, address);
59    serverAddress.port = NETWORK_PORT;
60    established=false;
61  }
[285]62
[217]63  bool ClientConnection::waitEstablished(int milisec){
64    for(int i=0; i<=milisec && !established; i++)
65      usleep(1000);
[448]66
[217]67    return established;
68  }
[285]69
70
[217]71  ENetPacket *ClientConnection::getPacket(ENetAddress &address){
[632]72    if(!buffer.isEmpty()) {
73      //std::cout << "###BUFFER IS NOT EMPTY###" << std::endl;
[217]74      return buffer.pop(address);
[632]75    }
76    else{
[217]77        return NULL;
[632]78    }
[217]79  }
[285]80
[369]81  ENetPacket *ClientConnection::getPacket(){
82    ENetAddress address;
83    return getPacket(address);
84  }
[514]85
[217]86  bool ClientConnection::queueEmpty(){
87    return buffer.isEmpty();
88  }
[285]89
[229]90  bool ClientConnection::createConnection(){
[217]91    network_threads.create_thread(boost::bind(boost::mem_fn(&ClientConnection::receiverThread), this));
[229]92    // wait 10 seconds for the connection to be established
93    return waitEstablished(10000);
[217]94  }
[285]95
[217]96  bool ClientConnection::closeConnection(){
97    quit=true;
98    network_threads.join_all();
99    established=false;
100    return true;
101  }
[285]102
103
[217]104  bool ClientConnection::addPacket(ENetPacket *packet){
105    if(server==NULL)
106      return false;
107    if(enet_peer_send(server, 1, packet)!=0)
108      return false;
[448]109    return true;
[217]110  }
[285]111
[217]112  bool ClientConnection::sendPackets(ENetEvent *event){
113    if(server==NULL)
114      return false;
[448]115    if(enet_host_service(client, event, NETWORK_SEND_WAIT)>=0){
116      return true;}
[285]117    else
[217]118      return false;
119  }
[285]120
[229]121  bool ClientConnection::sendPackets(){
122    ENetEvent event;
123    if(server==NULL)
124      return false;
[448]125    if(enet_host_service(client, &event, NETWORK_SEND_WAIT)>=0){
126      return true;}
[285]127    else
[229]128      return false;
129  }
[285]130
[217]131  void ClientConnection::receiverThread(){
132    // what about some error-handling here ?
133    enet_initialize();
134    atexit(enet_deinitialize);
135    ENetEvent event;
136    client = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
137    if(client==NULL)
138      // add some error handling here ==========================
139      quit=true;
140    //connect to the server
[369]141    if(!establishConnection()){
[217]142      quit=true;
[369]143      return;
144    }
[217]145    //main loop
146    while(!quit){
[605]147      //std::cout << "connection loop" << std::endl;
[620]148      if(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT)<0){
[217]149        // we should never reach this point
150        quit=true;
151        // add some error handling here ========================
152      }
153      switch(event.type){
154        // log handling ================
[352]155      case ENET_EVENT_TYPE_CONNECT:
[217]156      case ENET_EVENT_TYPE_RECEIVE:
[620]157        //std::cout << "got packet" << std::endl;
[217]158        processData(&event);
159        break;
160      case ENET_EVENT_TYPE_DISCONNECT:
[369]161        quit=true;
162        // server closed the connection
163        return;
[217]164        break;
[352]165      case ENET_EVENT_TYPE_NONE:
166        continue;
[217]167      }
168    }
169    // now disconnect
[285]170
171    if(!disconnectConnection())
[217]172    // if disconnecting failed destroy conn.
173      enet_peer_reset(server);
174    return;
175  }
[285]176
[217]177  bool ClientConnection::disconnectConnection(){
178    ENetEvent event;
[298]179    enet_peer_disconnect(server, 0);
[620]180    while(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT) > 0){
[217]181      switch (event.type)
182      {
[352]183        case ENET_EVENT_TYPE_NONE:
184        case ENET_EVENT_TYPE_CONNECT:
[217]185        case ENET_EVENT_TYPE_RECEIVE:
186          enet_packet_destroy(event.packet);
187          break;
188        case ENET_EVENT_TYPE_DISCONNECT:
189          return true;
190      }
191    }
192    enet_peer_reset(server);
[352]193    return false;
[217]194  }
[285]195
[217]196  bool ClientConnection::establishConnection(){
197    ENetEvent event;
198    // connect to peer
199    server = enet_host_connect(client, &serverAddress, NETWORK_CLIENT_CHANNELS);
200    if(server==NULL)
201      // error handling
202      return false;
203    // handshake
[620]204    if(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT)>0 && event.type == ENET_EVENT_TYPE_CONNECT){
[217]205      established=true;
206      return true;
207    }
208    else
209      return false;
210  }
[285]211
[217]212  bool ClientConnection::processData(ENetEvent *event){
[620]213    //std::cout << "got packet, pushing to queue" << std::endl;
[217]214    // just add packet to the buffer
215    // this can be extended with some preprocessing
216    return buffer.push(event);
217  }
[285]218
219
[217]220}
Note: See TracBrowser for help on using the repository browser.