Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/network/ConnectionManager.cc @ 374

Last change on this file since 374 was 369, checked in by scheusso, 17 years ago

PacketDecoder:

Extended Class to make inheriting easier…

-added virtual function, that can be implemented by lower classes

Client:

Added some function, changed some things (input, gamestate, connectionhandling)

Server:

same as client

File size: 6.1 KB
RevLine 
[173]1//
2// C++ Interface: ConnectionManager
3//
[285]4// Description: The Class ConnectionManager manages the servers conenctions to the clients.
5// each connection is provided by a new process. communication between master process and
[173]6// connection processes is provided by ...
7//
8//
[196]9// Author:  Oliver Scheuss
[173]10//
11
[285]12#include "ConnectionManager.h"
[173]13
14namespace network{
[285]15
[196]16  boost::thread_group network_threads;
[285]17
[196]18  void test(){
19    return;
20  }
[285]21
[173]22  ConnectionManager::ConnectionManager(){
23    quit=false;
24    client=NULL;
[196]25    bindAddress.host = ENET_HOST_ANY;
[173]26    bindAddress.port = NETWORK_PORT;
27  }
[285]28
[230]29  ConnectionManager::ConnectionManager(int port, std::string address){
[173]30    quit=false;
31    client=NULL;
[230]32    enet_address_set_host (& bindAddress, address.c_str());
[173]33    bindAddress.port = NETWORK_PORT;
34  }
[285]35
[230]36  ConnectionManager::ConnectionManager(int port, const char *address){
37    quit=false;
38    client=NULL;
39    enet_address_set_host (& bindAddress, address);
40    bindAddress.port = NETWORK_PORT;
41  }
[285]42
[204]43  ENetPacket *ConnectionManager::getPacket(ENetAddress &address){
[196]44    if(!buffer.isEmpty())
[204]45      return buffer.pop(address);
[196]46    else
47        return NULL;
[173]48  }
[285]49
[196]50  bool ConnectionManager::queueEmpty(){
51    return buffer.isEmpty();
[173]52  }
[285]53
[196]54  void ConnectionManager::createListener(){
55    network_threads.create_thread(boost::bind(boost::mem_fn(&ConnectionManager::receiverThread), this));
56//     boost::thread thr(boost::bind(boost::mem_fn(&ConnectionManager::receiverThread), this));
57    return;
58  }
[285]59
[196]60  bool ConnectionManager::quitListener(){
[173]61    quit=true;
[196]62    network_threads.join_all();
[173]63    return true;
64  }
[285]65
[196]66  bool ConnectionManager::addPacket(ENetPacket *packet, ENetPeer *peer){
[352]67    if(client==NULL)
[196]68      return false;
69    ClientList *temp=client;
70    while(peer->host != temp->event->peer->host){
71      temp=temp->next;
72      if(temp==NULL)
73        return false;
74    }
75    if(enet_peer_send(temp->event->peer, temp->ID, packet)!=0)
76      return false;
77    return true;
78  }
[285]79
[196]80  bool ConnectionManager::addPacket(ENetPacket *packet, int ID){
[229]81    if(client==NULL)
[196]82      return false;
83    ClientList *temp=client;
84    while(ID != temp->ID){
85      temp=temp->next;
86      if(temp==NULL)
87        return false;
88    }
89    if(enet_peer_send(temp->event->peer, temp->ID, packet)!=0)
90      return false;
91    else
92      return true;
93  }
[285]94
[196]95  bool ConnectionManager::addPacketAll(ENetPacket *packet){
96    ClientList *temp=client;
97    while(temp!=NULL){
98      if(enet_peer_send(temp->event->peer, temp->ID, packet)!=0)
99         return false;
100    }
101    return true;
102  }
[285]103
[196]104  bool ConnectionManager::sendPackets(ENetEvent *event){
105    if(server==NULL)
106      return false;
107    if(enet_host_service(server, event, NETWORK_SEND_WAIT)>=0)
108      return true;
[285]109    else
[196]110      return false;
111  }
[369]112 
113  bool ConnectionManager::sendPackets(){
114    ENetEvent event;
115    if(server==NULL)
116      return false;
117    if(enet_host_service(server, &event, NETWORK_SEND_WAIT)>=0)
118      return true;
119    else
120      return false;
121  }
[285]122
[196]123  void ConnectionManager::receiverThread(){
124    // what about some error-handling here ?
125    enet_initialize();
126    atexit(enet_deinitialize);
[173]127    ENetEvent event;
128    server = enet_host_create(&bindAddress, NETWORK_MAX_CONNECTIONS, 0, 0);
[369]129    if(server==NULL){
[173]130      // add some error handling here ==========================
131      quit=true;
[369]132      return;
133    }
[285]134
[173]135    while(!quit){
136      if(enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT)<0){
137        // we should never reach this point
138        quit=true;
139        // add some error handling here ========================
140      }
141      switch(event.type){
142        // log handling ================
[196]143        case ENET_EVENT_TYPE_CONNECT:
144        addClient(&event);
[173]145        break;
[196]146      case ENET_EVENT_TYPE_RECEIVE:
147        processData(&event);
[173]148        break;
[196]149      case ENET_EVENT_TYPE_DISCONNECT:
[173]150        // add some error/log handling here
151        clientDisconnect(event.peer);
152        break;
[352]153      case ENET_EVENT_TYPE_NONE:
154        break;
[173]155      }
156    }
[369]157    disconnectClients();
[173]158    // if we're finishied, destroy server
159    enet_host_destroy(server);
160  }
[369]161 
162  void ConnectionManager::disconnectClients(){
163    bool disconnected=false;
164    ENetEvent event;
165    ClientList *temp=client;
166    while(temp!=NULL){
167      enet_peer_disconnect(temp->event->peer, 0);
168      while( !disconnected && enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT) > 0){
169        switch (event.type)
170        {
171          case ENET_EVENT_TYPE_NONE:
172          case ENET_EVENT_TYPE_CONNECT:
173          case ENET_EVENT_TYPE_RECEIVE:
174            enet_packet_destroy(event.packet);
175            break;
176          case ENET_EVENT_TYPE_DISCONNECT:
177            disconnected=true;
178            break;
179        }
180      }
181      temp = temp->next;
182      disconnected=false;
183    }
184    return;
185  }
[285]186
[196]187  bool ConnectionManager::processData(ENetEvent *event){
188    // just add packet to the buffer
189    // this can be extended with some preprocessing
[204]190    return buffer.push(event);
[173]191  }
[285]192
[196]193  bool ConnectionManager::clientDisconnect(ENetPeer *peer){
[173]194    ClientList *temp=client;
[196]195    // do we have to remove the first item ?
196    if(temp->event->peer->host==peer->host){
[173]197      if(temp->next==NULL){
198        client=NULL;
199      } else{
200        client=temp->next;
201      }
202      delete temp;
203      return true;
204    } else {
205      while(temp->next!=NULL){
[196]206        if(temp->next->event->peer->host==peer->host){
207          // do a correct relink and delete the disconnected client
[173]208          ClientList *temp2=temp->next;
209          temp->next=temp2->next;
210          delete temp2;
211          return true;
212        } else
[196]213          //otherwise keep on searching ;)
[173]214          temp=temp->next;
215      }
216    }
217    return false;
218  }
[285]219
[196]220  bool ConnectionManager::addClient(ENetEvent *event){
[285]221
[196]222    // first client?
[173]223    if(client==NULL){
224      client =new ClientList;
225      client->ID=1;
226      client->next=NULL;
227      client->event = event;
228    } else {
[196]229      // otherwise add a new element to clientlist
230      ClientList *temp = client;
[173]231      int i=1;
232      while(temp->next != NULL){
233        temp=temp->next;
234        i++;
235      }
236      temp->next=new ClientList;
237      temp=temp->next;
238      temp->ID=i+1;
239      temp->event=event;
240      temp->next=NULL;
241    }
242    return true;
243  }
[285]244
245
[173]246}
Note: See TracBrowser for help on using the repository browser.