[ENet-discuss] tutorial application

Gerald Franz gerald.franz at tuebingen.mpg.de
Tue Jun 27 01:58:41 PDT 2006


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;
}



More information about the ENet-discuss mailing list