Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 348 was 346, checked in by rgrieder, 17 years ago
  • adjusted the entire source to compile under windows visual studio too:
  • added some ugly conversions
  • changed some illegal code pieces (gcc however accepted it)
  • added a few files from reto's framework to evade linker errors (no more dynamic linking)
  • inserted some 'return true' to justify the return type
  • excluded the levelLoader in the orxonox.cc (couldn't make it work, parsing error)
  • wrote about 5 code #branches to compensate for missing usleep() under windows
File size: 4.5 KB
Line 
1//
2// C++ Interface: ClientConnection
3//
4// Description: The Class ClientConnection manages the servers conenctions to the clients.
5// each connection is provided by a new process. communication between master process and
6// connection processes is provided by ...
7//
8//
9// Author:  Oliver Scheuss
10//
11
12#include "ClientConnection.h"
13
14// workaround for usleep(int) under windows
15#ifdef WIN32
16#include "winbase.h"
17#endif
18
19namespace network{
20
21  static boost::thread_group network_threads;
22
23  ClientConnection::ClientConnection(int port, std::string address){
24    quit=false;
25    server=NULL;
26    enet_address_set_host(&serverAddress, address.c_str());
27    serverAddress.port = NETWORK_PORT;
28    established=false;
29  }
30
31  ClientConnection::ClientConnection(int port, const char *address){
32    quit=false;
33    server=NULL;
34    enet_address_set_host(&serverAddress, address);
35    serverAddress.port = NETWORK_PORT;
36    established=false;
37  }
38
39  bool ClientConnection::waitEstablished(int milisec){
40    for(int i=0; i<=milisec && !established; i++)
41// under windows, use Sleep(milliseconds) instead of usleep(microseconds)
42#ifdef WIN32
43      Sleep(1);
44#else
45      usleep(1000);
46#endif
47    return established;
48  }
49
50
51  ENetPacket *ClientConnection::getPacket(ENetAddress &address){
52    if(!buffer.isEmpty())
53      return buffer.pop(address);
54    else
55        return NULL;
56  }
57
58  bool ClientConnection::queueEmpty(){
59    return buffer.isEmpty();
60  }
61
62  bool ClientConnection::createConnection(){
63    network_threads.create_thread(boost::bind(boost::mem_fn(&ClientConnection::receiverThread), this));
64    // wait 10 seconds for the connection to be established
65    return waitEstablished(10000);
66  }
67
68  bool ClientConnection::closeConnection(){
69    quit=true;
70    network_threads.join_all();
71    established=false;
72    return true;
73  }
74
75
76  bool ClientConnection::addPacket(ENetPacket *packet){
77    if(server==NULL)
78      return false;
79    if(enet_peer_send(server, 1, packet)!=0)
80      return false;
81    else
82      return true;
83  }
84
85  bool ClientConnection::sendPackets(ENetEvent *event){
86    if(server==NULL)
87      return false;
88    if(enet_host_service(client, event, NETWORK_SEND_WAIT)>=0)
89      return true;
90    else
91      return false;
92  }
93
94  bool ClientConnection::sendPackets(){
95    ENetEvent event;
96    if(server==NULL)
97      return false;
98    if(enet_host_service(client, &event, NETWORK_SEND_WAIT)>=0)
99      return true;
100    else
101      return false;
102  }
103
104  void ClientConnection::receiverThread(){
105    // what about some error-handling here ?
106    enet_initialize();
107    atexit(enet_deinitialize);
108    ENetEvent event;
109    client = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
110    if(client==NULL)
111      // add some error handling here ==========================
112      quit=true;
113    //connect to the server
114    if(!establishConnection())
115      quit=true;
116    //main loop
117    while(!quit){
118      if(enet_host_service(client, &event, NETWORK_WAIT_TIMEOUT)<0){
119        // we should never reach this point
120        quit=true;
121        // add some error handling here ========================
122      }
123      switch(event.type){
124        // log handling ================
125      case ENET_EVENT_TYPE_RECEIVE:
126        processData(&event);
127        break;
128      case ENET_EVENT_TYPE_DISCONNECT:
129        // add some error/log handling here
130        // extend =====================
131        break;
132      }
133    }
134    // now disconnect
135
136    if(!disconnectConnection())
137    // if disconnecting failed destroy conn.
138      enet_peer_reset(server);
139    return;
140  }
141
142  bool ClientConnection::disconnectConnection(){
143    ENetEvent event;
144//     enet_peer_disconnect(server);
145    enet_peer_disconnect(server, 0);
146    while(enet_host_service(client, &event, NETWORK_WAIT_TIMEOUT) > 0){
147      switch (event.type)
148      {
149        case ENET_EVENT_TYPE_RECEIVE:
150          enet_packet_destroy(event.packet);
151          break;
152        case ENET_EVENT_TYPE_DISCONNECT:
153          return true;
154      }
155    }
156    enet_peer_reset(server);
157  }
158
159  bool ClientConnection::establishConnection(){
160    ENetEvent event;
161    // connect to peer
162    server = enet_host_connect(client, &serverAddress, NETWORK_CLIENT_CHANNELS);
163    if(server==NULL)
164      // error handling
165      return false;
166    // handshake
167    if(enet_host_service(client, &event, NETWORK_WAIT_TIMEOUT)>0 && event.type == ENET_EVENT_TYPE_CONNECT){
168      established=true;
169      return true;
170    }
171    else
172      return false;
173  }
174
175  bool ClientConnection::processData(ENetEvent *event){
176    // just add packet to the buffer
177    // this can be extended with some preprocessing
178    return buffer.push(event);
179  }
180
181
182}
Note: See TracBrowser for help on using the repository browser.