Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/merge/src/network/ClientConnection.cc @ 1299

Last change on this file since 1299 was 1279, checked in by scheusso, 16 years ago

adapted boost threads in clientconnection
added trap to runscript (xset r, autorepeat)
had to change assff back to assf3 due to some network issues

File size: 6.7 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, (C) 2007
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29//
30// C++ Interface: ClientConnection
31//
32// Description: The Class ClientConnection manages the servers conenctions to the clients.
33// each connection is provided by a new process. communication between master process and
34// connection processes is provided by ...
35//
36//
37// Author:  Oliver Scheuss
38//
39
40#include "ClientConnection.h"
41
42#include <iostream>
43// boost.thread library for multithreading support
44#include <boost/bind.hpp>
45
46#include "util/Sleep.h"
47#include "core/Debug.h"
48
49namespace network
50{
51  //static boost::thread_group network_threads;
52
53  ClientConnection::ClientConnection(int port, std::string address) {
54    quit=false;
55    server=NULL;
56    enet_address_set_host(&serverAddress, address.c_str());
57    serverAddress.port = NETWORK_PORT;
58    established=false;
59  }
60
61  ClientConnection::ClientConnection(int port, const char *address) {
62    quit=false;
63    server=NULL;
64    enet_address_set_host(&serverAddress, address);
65    serverAddress.port = NETWORK_PORT;
66    established=false;
67  }
68
69  bool ClientConnection::waitEstablished(int milisec) {
70    for(int i=0; i<=milisec && !established; i++)
71      usleep(1000);
72
73    return established;
74  }
75
76
77  ENetPacket *ClientConnection::getPacket(ENetAddress &address) {
78    if(!buffer.isEmpty()) {
79      //std::cout << "###BUFFER IS NOT EMPTY###" << std::endl;
80      return buffer.pop(address);
81    }
82    else{
83      return NULL;
84    }
85  }
86
87  ENetPacket *ClientConnection::getPacket() {
88    ENetAddress address; //sems that address is not needed
89    return getPacket(address);
90  }
91
92  bool ClientConnection::queueEmpty() {
93    return buffer.isEmpty();
94  }
95
96  bool ClientConnection::createConnection() {
97    receiverThread_ = new boost::thread(boost::bind(&ClientConnection::receiverThread, this));
98    //network_threads.create_thread(boost::bind(boost::mem_fn(&ClientConnection::receiverThread), this));
99    // wait 10 seconds for the connection to be established
100    return waitEstablished(10000);
101  }
102
103  bool ClientConnection::closeConnection() {
104    quit=true;
105    //network_threads.join_all();
106    receiverThread_->join();
107    established=false;
108    return true;
109  }
110
111
112  bool ClientConnection::addPacket(ENetPacket *packet) {
113    if(server==NULL)
114      return false;
115    if(packet==NULL){
116      COUT(3) << "Cl.con: addpacket: invalid packet" << std::endl;
117      return false;
118    }
119    if(enet_peer_send(server, 0, packet)<0)
120      return false;
121    else
122      return true;
123  }
124
125  bool ClientConnection::sendPackets(ENetEvent *event) {
126    if(server==NULL)
127      return false;
128    if(enet_host_service(client, event, NETWORK_SEND_WAIT)>=0){
129      return true;}
130    else
131      return false;
132  }
133
134  bool ClientConnection::sendPackets() {
135    ENetEvent event;
136    if(server==NULL)
137      return false;
138    if(enet_host_service(client, &event, NETWORK_SEND_WAIT)>=0){
139      return true;}
140    else
141      return false;
142  }
143
144  void ClientConnection::receiverThread() {
145    // what about some error-handling here ?
146    enet_initialize();
147    atexit(enet_deinitialize);
148    ENetEvent event;
149    client = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
150    if(client==NULL)
151      // add some error handling here ==========================
152      quit=true;
153    //connect to the server
154    if(!establishConnection()){
155      quit=true;
156      return;
157    }
158    //main loop
159    while(!quit){
160      //std::cout << "connection loop" << std::endl;
161      if(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT)<0){
162        // we should never reach this point
163        quit=true;
164        // add some error handling here ========================
165      }
166      switch(event.type){
167        // log handling ================
168      case ENET_EVENT_TYPE_CONNECT:
169      case ENET_EVENT_TYPE_RECEIVE:
170        COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
171        if ( !processData(&event) ) COUT(2) << "Current packet was not pushed to packetBuffer -> ev ongoing SegFault" << std::endl;
172        COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
173        break;
174      case ENET_EVENT_TYPE_DISCONNECT:
175        quit=true;
176        // server closed the connection
177        return;
178        break;
179      case ENET_EVENT_TYPE_NONE:
180        continue;
181      }
182      //receiverThread_->yield();
183    }
184    // now disconnect
185
186    if(!disconnectConnection())
187      // if disconnecting failed destroy conn.
188      enet_peer_reset(server);
189    return;
190  }
191
192  bool ClientConnection::disconnectConnection() {
193    ENetEvent event;
194    enet_peer_disconnect(server, 0);
195    while(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT) > 0){
196      switch (event.type)
197      {
198      case ENET_EVENT_TYPE_NONE:
199      case ENET_EVENT_TYPE_CONNECT:
200      case ENET_EVENT_TYPE_RECEIVE:
201        enet_packet_destroy(event.packet);
202        break;
203      case ENET_EVENT_TYPE_DISCONNECT:
204        return true;
205      }
206    }
207    enet_peer_reset(server);
208    return false;
209  }
210
211  bool ClientConnection::establishConnection() {
212    ENetEvent event;
213    // connect to peer (server is type ENetPeer*)
214    server = enet_host_connect(client, &serverAddress, NETWORK_CLIENT_CHANNELS);
215    if(server==NULL)
216      // error handling
217      return false;
218    // handshake
219    if(enet_host_service(client, &event, NETWORK_CLIENT_TIMEOUT)>0 && event.type == ENET_EVENT_TYPE_CONNECT){
220      established=true;
221      return true;
222    }
223    else
224      return false;
225  }
226
227  bool ClientConnection::processData(ENetEvent *event) {
228    COUT(5) << "Cl.Con: got packet, pushing to queue" << std::endl;
229    // just add packet to the buffer
230    // this can be extended with some preprocessing
231    return buffer.push(event);
232  }
233
234}
Note: See TracBrowser for help on using the repository browser.