Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 21, 2009, 12:27:19 AM (15 years ago)
Author:
scheusso
Message:

rest of the cleanup ( mostly client connection handling)
network is now single-threaded ( only in order to become multithreaded again, but thats another story ;) )

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/netp5/src/network/ClientConnection.cc

    r3198 r3202  
    2727 */
    2828
    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 
    4029#include "ClientConnection.h"
    4130
    42 #include <enet/enet.h>
    4331#include <iostream>
    4432#include <cassert>
    45 // boost.thread library for multithreading support
    46 #include <boost/thread/thread.hpp>
    47 #include <boost/bind.hpp>
    48 #include <boost/thread/recursive_mutex.hpp>
    4933
    50 #include "util/Sleep.h"
    5134#include "util/Debug.h"
    5235
    5336namespace orxonox
    5437{
    55   //static boost::thread_group network_threads;
     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 = 5;
     41  const unsigned int NETWORK_CLIENT_CHANNELS = 2;
    5642
    57   static boost::recursive_mutex enet_mutex_g;
    5843
    59   ClientConnection::ClientConnection(int port, const std::string& address) {
    60     quit_=false;
    61     server=NULL;
    62     serverAddress = new ENetAddress();
    63     enet_address_set_host(serverAddress, address.c_str());
    64     serverAddress->port = port;
    65     established=false;
    66   }
    67 
    68   ClientConnection::ClientConnection(int port, const char *address) {
    69     quit_=false;
    70     server=NULL;
    71     serverAddress = new ENetAddress();
    72     enet_address_set_host(serverAddress, address);
    73     serverAddress->port = port;
    74     established=false;
    75   }
    76 
    77   bool ClientConnection::waitEstablished(int milisec) {
    78     for(int i=0; i<=milisec && !established; i++)
    79       msleep(1);
    80 
    81     return established;
     44  ClientConnection::ClientConnection():
     45    server_(NULL),
     46    established_(false)
     47  {
     48    this->serverAddress_ = new ENetAddress();
     49    //set standard address and port
     50    enet_address_set_host(this->serverAddress_, "127.0.0.1");
     51    serverAddress_->port = NETWORK_PORT;
    8252  }
    8353
    8454  ClientConnection::~ClientConnection(){
    85     if(established)
     55    if(this->established_)
    8656      closeConnection();
    87     delete serverAddress; // surely was created
     57    delete this->serverAddress_; // surely was created
    8858  }
    8959
    90   ENetEvent *ClientConnection::getEvent(){
    91     if(!buffer.isEmpty())
    92       return buffer.pop();
    93     else
    94       return NULL;
    95   }
    96 
    97   bool ClientConnection::queueEmpty() {
    98     return buffer.isEmpty();
    99   }
    100 
    101   bool ClientConnection::createConnection() {
    102     receiverThread_ = new boost::thread(boost::bind(&ClientConnection::receiverThread, this));
    103     //network_threads.create_thread(boost::bind(boost::mem_fn(&ClientConnection::receiverThread), this));
    104     // wait 10 seconds for the connection to be established
    105     return waitEstablished(NETWORK_CLIENT_CONNECT_TIMEOUT);
    106   }
    107 
    108   bool ClientConnection::closeConnection() {
    109     quit_=true;
    110     //network_threads.join_all();
    111     receiverThread_->join();
    112     established=false;
    113     return true;
    114   }
    115 
    116 
    117   bool ClientConnection::addPacket(ENetPacket *packet) {
    118     if(server==NULL)
    119       return false;
    120     if(packet==NULL){
    121       COUT(3) << "Cl.con: addpacket: invalid packet" << std::endl;
     60  bool ClientConnection::establishConnection()
     61  {
     62    ENetEvent event;
     63   
     64    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
     65    if ( this->host_ == NULL )
     66    {
     67      COUT(2) << "ClientConnection: host_ == NULL" << std::endl;
     68      // error handling
    12269      return false;
    12370    }
    124     boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    125     if(enet_peer_send(server, 0, packet)<0)
    126       return false;
    127     else
    128       return true;
    129   }
    130 
    131   bool ClientConnection::sendPackets() {
    132     if(server==NULL)
    133       return false;
    134     boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    135     enet_host_flush(client);
    136     lock.unlock();
    137     return true;
    138   }
    139 
    140   void ClientConnection::receiverThread() {
    141     // what about some error-handling here ?
    142     atexit(enet_deinitialize);
    143     ENetEvent *event;
     71    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CLIENT_CHANNELS);
     72    if ( this->server_==NULL )
    14473    {
    145       boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    146       enet_initialize();
    147       client = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
    148       lock.unlock();
    149     }
    150     if(client==NULL) {
    151       COUT(2) << "ClientConnection: could not create client host" << std::endl;
    152       // add some error handling here ==========================
    153       quit_=true;
    154     }
    155     //connect to the server
    156     if(!establishConnection()){
    157       COUT(2) << "clientConn: receiver thread: could not establishConnection" << std::endl;
    158       quit_=true;
    159       return;
    160     }
    161     event = new ENetEvent;
    162     //main loop
    163     while(!quit_){
    164       //std::cout << "connection loop" << std::endl;
    165       {
    166         boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    167         if(enet_host_service(client, event, NETWORK_CLIENT_WAIT_TIME)<0){
    168           // we should never reach this point
    169 //              assert(0);
    170           printf("ClientConnection: ENet returned with an error!\n");
    171 //           quit_=true;
    172           continue;
    173           // add some error handling here ========================
    174         }
    175         lock.unlock();
    176       }
    177       switch(event->type){
    178         // log handling ================
    179       case ENET_EVENT_TYPE_CONNECT:
    180         break;
    181       case ENET_EVENT_TYPE_RECEIVE:
    182         //COUT(5) << "Cl.Con: receiver-Thread while loop: got new packet" << std::endl;
    183         if ( !processData(event) ) COUT(2) << "Current packet was not pushed to packetBuffer -> ev ongoing SegFault" << std::endl;
    184         //COUT(5) << "Cl.Con: processed Data in receiver-thread while loop" << std::endl;
    185         event = new ENetEvent;
    186         break;
    187       case ENET_EVENT_TYPE_DISCONNECT:
    188         quit_=true;
    189         printf("Received disconnect Packet from Server!\n");
    190         // server closed the connection
    191         return;
    192         break;
    193       case ENET_EVENT_TYPE_NONE:
    194         //receiverThread_->yield();
    195         msleep(1);
    196         break;
    197       }
    198     }
    199     delete event;
    200     // now disconnect
    201 
    202     if(!disconnectConnection())
    203     {
    204       printf("could not disconnect properly\n");
    205       // if disconnecting failed destroy conn.
    206       boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    207       enet_peer_reset(server);
    208     }
    209     else
    210       printf("properly disconnected\n");
    211     return;
    212   }
    213 
    214   bool ClientConnection::disconnectConnection() {
    215     ENetEvent event;
    216     if(this->quit_)
    217       return true;
    218     boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    219     enet_peer_disconnect(server, 0);
    220     while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME) >= 0){
    221       switch (event.type)
    222       {
    223       case ENET_EVENT_TYPE_NONE:
    224       case ENET_EVENT_TYPE_CONNECT:
    225       case ENET_EVENT_TYPE_RECEIVE:
    226         enet_packet_destroy(event.packet);
    227         break;
    228       case ENET_EVENT_TYPE_DISCONNECT:
    229         printf("received disconnect confirmation from server");
    230         return true;
    231       }
    232     }
    233     enet_peer_reset(server);
    234     return false;
    235   }
    236 
    237   bool ClientConnection::establishConnection() {
    238     ENetEvent event;
    239     // connect to peer (server is type ENetPeer*)
    240     boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
    241     server = enet_host_connect(client, serverAddress, NETWORK_CLIENT_CHANNELS);
    242     if(server==NULL) {
    24374      COUT(2) << "ClientConnection: server == NULL" << std::endl;
    24475      // error handling
     
    24677    }
    24778    // handshake
    248     while(enet_host_service(client, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && !quit_){
    249       if( event.type == ENET_EVENT_TYPE_CONNECT ){
    250         established=true;
     79    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++ )
     80    {
     81      if( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && event.type == ENET_EVENT_TYPE_CONNECT )
     82      {
     83        this->established_=true;
    25184        return true;
    25285      }
    25386    }
    254     COUT(2) << "ClientConnection: enet_host_service < 0 or event.type != ENET_EVENT_TYPE_CONNECT # EVENT:" << event.type << std::endl;
     87    COUT(1) << "Could not connect to server" << endl;
     88  }
     89
     90  bool ClientConnection::closeConnection() {
     91    ENetEvent event;
     92   
     93    if ( !this->established_ )
     94      return true;
     95    this->established_ = false;
     96    enet_peer_disconnect(this->server_, 0);
     97    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++)
     98    {
     99      if ( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME) >= 0 )
     100      {
     101        switch (event.type)
     102        {
     103          case ENET_EVENT_TYPE_NONE:
     104          case ENET_EVENT_TYPE_CONNECT:
     105            break;
     106          case ENET_EVENT_TYPE_RECEIVE:
     107            enet_packet_destroy(event.packet);
     108            break;
     109          case ENET_EVENT_TYPE_DISCONNECT:
     110            COUT(4) << "received disconnect confirmation from server" << endl;
     111            return true;
     112        }
     113      }
     114    }
     115    enet_peer_reset( this->server_ );
    255116    return false;
    256117  }
    257118
    258   bool ClientConnection::processData(ENetEvent *event) {
    259     COUT(5) << "Cl.Con: got packet, pushing to queue" << std::endl;
    260     // just add packet to the buffer
    261     // this can be extended with some preprocessing
    262     return buffer.push(event);
     119
     120  bool ClientConnection::addPacket(ENetPacket *packet) {
     121    assert( this->server_ );
     122    assert( packet );
     123    return Connection::addPacket( packet, this->server_ );
     124  }
     125
     126  void ClientConnection::addClient(ENetEvent* event)
     127  {
     128    assert(0);
     129  }
     130  void ClientConnection::disconnectPeer(ENetEvent* event)
     131  {
     132    this->established_=false;
     133    COUT(1) << "Received disconnect Packet from Server!" << endl;
     134        // server closed the connection
    263135  }
    264136
Note: See TracChangeset for help on using the changeset viewer.