[ENet-discuss] tutorial application

Lee Salzman lsalzman1 at cox.net
Tue Jun 27 08:20:40 PDT 2006


Try not to instantiate and bytewise-copy ENetPeers like that. The result 
will most certainly 'cause all manner of random bugs, since they were 
never designed to be used as such.

Lee

Gerald Franz wrote:
> Hello everybody,
> 
> I am new to the list and enet, and I am trying to put the
> snippets of the tutorial into a little test application.
> After one day I have almost succeeded but are faced with
> two puzzling problems (enet-1.0.tar.gz):
> - When the client requests an exit, the server often hangs
> or crashes in the final enet_peer_reset()
> - The application often spends too much time in
> enet_host_service() in the main loop on one computer and
> therefore fails to send for itself packages. Could it be
> that it could take a lot of time to to reply to these many
> reliable packages?
> 
> If these bugs can be solved, I am happy if my little piece
> of code could be inncluded as a minimal tutorial example. I
> gladly would rewrite it in pure C.
> 
> Thanks
> Gerald
> 
> // enet test application, 2006-06-23 by
> gerald.franz at viremo.de
> #include <enet/enet.h>
> 
> #include <sys/timeb.h>
> #if !defined (WIN32)
> #  include <sys/time.h>
> #else
> # include <windows.h>
> #endif
> 
> #include <cstdlib>
> #include <iostream>
> #include <sstream>
> using namespace std;
> 
> 
> double timestamp() {
> #if defined (WIN32)
>   __int64 freq, count;
>   //check for high resolution timer
>   if(QueryPerformanceFrequency((LARGE_INTEGER*)&freq)) {
>     //high resolution timer available - use it!
>     double dResolution = 1.0 / (double)freq;
>     QueryPerformanceCounter((LARGE_INTEGER*)&count);
>     double dSeconds = (double)count * dResolution;
>     static long secsFirstCall = (long)dSeconds;
>     return dSeconds - (double)secsFirstCall;
>   }
>   else
>   {
>     struct timeb tp;
>     ftime(&tp);
>     return double(tp.time)+0.001*double(tp.millitm);
>   }
> #else
>   static struct timeval time;
>   gettimeofday(&time, 0);
>   static long secsFirstCall=time.tv_sec;
>   return (double)(time.tv_sec-secsFirstCall) +
> (double)time.tv_usec/(1000.0*1000.0);
> #endif
> }
> 
> 
> int main (int argc, char ** argv) {
>     if(argc<2) {
>         cerr << "usage: " << argv[0] << " port [server
> name]\n";
>         return 1;
>     }
> 
>     // network initialization:
>     if (enet_initialize() != 0) {
>         cerr << "An error occurred while initializing
> ENet.\n";
>         return 1;
>     }
>     atexit (enet_deinitialize);
>     unsigned int nContainers=16;
>     unsigned int waitTime=5;    
> 	enet_time_set(0);
>     ENetEvent event;
>     ENetHost * host=0;
>     ENetPeer * peer=0;
>     ENetAddress address;
>     address.port = atoi(argv[1]); // Bind the server to
> port
>     bool isServer=(argc < 3);
> 
>     if(argc < 3) { // initialize server:
>         clog << "I am server..." << endl;
>         
>         address.host = ENET_HOST_ANY;
>         host = enet_host_create (&address, // the address
> to bind the server host to 
>                                       1,   // allow only 1
> client and/or outgoing connections
>                                       0,   // assume any
> amount of incoming bandwidth
>                                       0);  // assume any
> amount of outgoing bandwidth
>         if (!host) {
>             cerr << "An error occurred while trying to
> create an ENet server host.\n";
>             exit (EXIT_FAILURE);
>         }        
>     }
>     else { // initialize client:
>         clog << "I am client..."<< endl;
>         
>         host = enet_host_create (0, // create a client host
>                 1, // allow only 1 outgoing connection
>                 0, // use 57600 / 8 for 56K modem with 56
> Kbps downstream bandwidth
>                 0);// use 14400 / 8 for 56K modem with 14
> Kbps upstream bandwidth
> 
>         if (!host) {
>             cerr << "An error occurred while trying to
> create an ENet client host.\n";
>             exit (EXIT_FAILURE);
>         }
>         
>         // connect to server:
>         enet_address_set_host (&address, argv[2]);
>         peer = enet_host_connect (host, &address, 2);    
>         if (!peer) {
>            cerr << "No available peers for initiating an
> ENet connection.\n";
>            exit (EXIT_FAILURE);
>         }
>         if (enet_host_service (host, &event, 5000) > 0 &&
>                 event.type == ENET_EVENT_TYPE_CONNECT) {
>             clog << "Connection to server succeeded." <<
> endl;
>         }
>         else {
>             /* Either the 5 seconds are up or a disconnect
> event was */
>             /* received. Reset the peer in the event the 5
> seconds   */
>             /* had run out without any significant event.
>            */
>             enet_peer_reset (peer);
>             peer=0;
>             cerr << "Connection to server failed.\n";
>         }        
>     }
>         
>     unsigned int sendCounter=0;
>     unsigned int recvCounter=0;
>     unsigned int sendPerSec=0, recvPerSec=0;
>     double tLastFps=timestamp();
>     unsigned int fps=0;
> 
>     // main loop:
>     int running=1;
>     while(running) {
>         //clog << "---" << endl;
>         double tNow=timestamp();
>         ++fps;
>         if(tNow>=tLastFps+1.0) {
>             cout << tNow-tLastFps << " secs, " << fps << "
> fps, containers sent per sec:" << sendPerSec << " recv:" <<
> recvPerSec
>                 << " total sent:" << sendCounter << "
> recv:" << recvCounter << endl;
>             sendPerSec=recvPerSec=fps=0;
>             tLastFps=tNow;
>         }
> 
>         // processing incoming events:
>         while (running && (enet_host_service (host, &event,
> waitTime) > 0)) {
>             switch (event.type) {
>             case ENET_EVENT_TYPE_CONNECT: {
>                 clog << "  A new client connected from " <<
> event.peer -> address.host 
>                     << ":" << event.peer -> address.port <<
> endl;
>                 
>                 ostringstream buf;
>                 buf << event.peer -> address.host << ":" <<
> event.peer -> address.port << ends;
>                 event.peer -> data = new
> char[buf.str().size()+1];
>                 strncpy((char*)event.peer ->
> data,buf.str().c_str(),buf.str().size());
> 
>                 if(peer) delete peer;
>                 peer=new ENetPeer;
>                 memcpy(peer,event.peer,sizeof(ENetPeer));
>                 //cout << "sizeof(ENetPeer):" <<
> sizeof(ENetPeer) << endl;
>                 break;
>             }
>             case ENET_EVENT_TYPE_RECEIVE:
>                 ++recvCounter;
>                 ++recvPerSec;
>                 /*
>                 clog << "  A packet of length " <<
> event.packet -> dataLength
>                     << " containing [" << event.packet ->
> data
>                     << "] was received from " <<
> (char*)event.peer -> data
>                     << " on channel " <<
> static_cast<int>(event.channelID) << endl;
>     */
>                 enet_packet_destroy (event.packet); //
> clean up the packet now that we're done using it
>                 break;
>                
>             case ENET_EVENT_TYPE_DISCONNECT:
>                 clog << "  host disconnected." << endl;
>                 event.peer -> data = NULL; // Reset the
> peer's client information.
>                 //delete peer;
>                 //peer=0;
>                 running=0;
>             default:
>                 break;
>             }
>         }
>         //clog << "processing events done." << endl;
>         
>         if(peer) {
>             //clog << "sending data..." << flush;
>             for(unsigned int i=0; i<nContainers; ++i) {
>                 char data[256];
>                 int reliable=sendCounter%2;
>                 ++sendPerSec;
>                 ostringstream buf;
>                 buf << (isServer? "msg by server: " : "msg
> by client: "); 
>                 buf << ++sendCounter;
>                 buf << (reliable ? " reliable" : "
> unreliable");
>                 strncpy(data,buf.str().c_str(),255);
>                 ENetPacket * packet = enet_packet_create
> (data, 256, reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
>                 if(isServer) {
>                     for(unsigned int i=0;
> i<host->peerCount; ++i)
>                         enet_peer_send (&host->peers[i],
> reliable, packet);
>                     //enet_host_broadcast (host, reliable,
> packet);
>                 }
>                 else enet_peer_send (peer, reliable,
> packet); // queue the packet to be sent to the peer over
> channel id 0
>             }
> 
>             //enet_host_flush (host); // not necessary,
> included in enet_host_service
>             //clog << "sending data done." << endl;
>         }
>         
>         // gently terminate connection from client side
> after 200.000 packages:
>         if(peer&&!isServer&&sendCounter>=20000) {
>             clog << "disconnecting..." << endl;
>             enet_peer_disconnect (peer, 0);
>         }
>     } // main loop
> 
>     if(peer) {
>         clog << "resetting peer..." << flush;
>         enet_peer_reset (peer);
>         clog << " done." << endl;
>     }
>     
>     clog << "closing down..." << flush;
>     enet_host_destroy(host);
>     clog << " done." << endl;
>     return 0;
> }
> 
> _______________________________________________
> ENet-discuss mailing list
> ENet-discuss at cubik.org
> http://lists.cubik.org/mailman/listinfo/enet-discuss
> 



More information about the ENet-discuss mailing list