Changeset 3202 for code/branches/netp5/src/network/ClientConnection.cc
- Timestamp:
- Jun 21, 2009, 12:27:19 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/netp5/src/network/ClientConnection.cc
r3198 r3202 27 27 */ 28 28 29 //30 // C++ Interface: ClientConnection31 //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 and34 // connection processes is provided by ...35 //36 //37 // Author: Oliver Scheuss38 //39 40 29 #include "ClientConnection.h" 41 30 42 #include <enet/enet.h>43 31 #include <iostream> 44 32 #include <cassert> 45 // boost.thread library for multithreading support46 #include <boost/thread/thread.hpp>47 #include <boost/bind.hpp>48 #include <boost/thread/recursive_mutex.hpp>49 33 50 #include "util/Sleep.h"51 34 #include "util/Debug.h" 52 35 53 36 namespace orxonox 54 37 { 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; 56 42 57 static boost::recursive_mutex enet_mutex_g;58 43 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; 82 52 } 83 53 84 54 ClientConnection::~ClientConnection(){ 85 if( established)55 if(this->established_) 86 56 closeConnection(); 87 delete serverAddress; // surely was created57 delete this->serverAddress_; // surely was created 88 58 } 89 59 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 122 69 return false; 123 70 } 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 ) 144 73 { 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 server156 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 loop163 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 point169 // 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 connection191 return;192 break;193 case ENET_EVENT_TYPE_NONE:194 //receiverThread_->yield();195 msleep(1);196 break;197 }198 }199 delete event;200 // now disconnect201 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 else210 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) {243 74 COUT(2) << "ClientConnection: server == NULL" << std::endl; 244 75 // error handling … … 246 77 } 247 78 // 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; 251 84 return true; 252 85 } 253 86 } 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_ ); 255 116 return false; 256 117 } 257 118 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 263 135 } 264 136
Note: See TracChangeset
for help on using the changeset viewer.