[ENet-discuss] tutorial application

Gerald Franz gerald.franz at tuebingen.mpg.de
Wed Jun 28 00:22:48 PDT 2006


Hello,

On Tue, 27 Jun 2006 08:20:40 -0700
 Lee Salzman <lsalzman1 at cox.net> wrote:
> 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.

thanks for the advice, now everything works fine! I have
attached my polished test application in the hope that it
might be of use as starting point for other enet beginners.
We will now probably take enet as base of our distributed
virtual reality software (velib.kyb.mpg.de). 

Thanks again,
Gerald

// enet example application, written 2006-06-27 by
gerald.franz at viremo.de
// based on the enet tutorial. Thanks to the original
author!

#include <enet/enet.h>

#include <stdlib.h>
#include <stdio.h>

#include <sys/timeb.h>
#if !defined (WIN32)
#  include <sys/time.h>
#else
# include <windows.h>
#endif

//--- function timestamp
-------------------------------------------
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);
    return (double)count * dResolution;
  }
  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
}


//--- main
---------------------------------------------------------

int main (int argc, char ** argv) {
    // basic traffic control variables:
    unsigned int packetSize=256;// size of a single packet
to be sent
    unsigned int nPackets=8;    // number of packets to be
sent per frame
    unsigned int nPacketsMax=200000; // total number of
packets to before application terminates, use 0 to disable
    unsigned int waitTime=5;    // number of milliseconds
to wait for network events, corresponding to time between
frames
    int verbose=0;              // should complete traffic
be dumped to stdout?

    if(argc<2) {
        fprintf(stderr,"usage: %s port [server
name]\n",argv[0]);
        return 1;
    }

    // network initialization:
    if (enet_initialize() != 0) {
        fprintf(stderr,"An error occurred while
initializing ENet.\n");
        return 1;
    }
    atexit (enet_deinitialize);

	enet_time_set(0);
    ENetEvent event;
    ENetHost * host=0;
    ENetPeer * peer=0;
    ENetAddress address;
    address.port = atoi(argv[1]); // bind connection to
this port
    int isServer=(argc < 3)?1:0;

    if(argc < 3) { // initialize server:
        printf("I am server...\n");
        fflush(stdout);
        
        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) {
            fprintf(stderr,"An error occurred while trying
to create an ENet server host.\n");
            exit (EXIT_FAILURE);
        }        
    }
    else { // initialize client:
        printf("I am client...\n");
        fflush(stdout);
        
        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) {
            fprintf(stderr,"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);    
        peer->data=0; // use this as mark that connection
is not yet acknowledged
        if (!peer) {
           fprintf(stderr,"No available peers for
initiating an ENet connection.\n");
           exit (EXIT_FAILURE);
        }
    }
        
    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) {
        double tNow=timestamp();
        ++fps;
        if(tNow>=tLastFps+1.0) {
            printf("%f secs, %u fps, containers sent per
sec:%u recv:%u total sent:%u recv: %u\n",
                tNow-tLastFps,fps,sendPerSec,recvPerSec,sendCounter,recvCounter);
            fflush(stdout);
            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: {
                printf("  A new connected has been
established to %u:%u\n", 
                    event.peer -> address.host,event.peer
-> address.port);
                fflush(stdout);
                
                char buf[64];
                sprintf(buf,"%u:%u",event.peer ->
address.host, event.peer -> address.port);
                int buflen=strlen(buf);
                event.peer -> data=malloc(buflen+1);
                strncpy((char*)event.peer ->
data,buf,buflen);
                peer=event.peer;
                break;
            }
            case ENET_EVENT_TYPE_RECEIVE:
                ++recvCounter;
                ++recvPerSec;
                
                if(verbose) {
                    printf("  A packet of length %u
containing [%s] was received from %s on channel %u\n",
                        event.packet ->
dataLength,event.packet -> data,(char*)event.peer ->
data,event.channelID);
                    fflush(stdout);
                }
                    
                enet_packet_destroy (event.packet); //
clean up the packet now that we're done using it
                break;
               
            case ENET_EVENT_TYPE_DISCONNECT:
                printf("  host disconnected.\n");
                fflush(stdout);
                free(event.peer -> data);
                event.peer -> data = 0; // reset the peer's
client information.
                peer=0;
                running=0;
            default:
                break;
            }
        }
        
        if(peer&&peer->data) { // send some data:
            unsigned int i;
            for(i=0; i<nPackets; ++i) {
                char * data=(char*)malloc(packetSize);
                int reliable=sendCounter%2;
                ++sendPerSec;
                sprintf(data,"msg by %s:%u, %s", isServer?
"server":"client", ++sendCounter,
                    reliable ? "reliable" : "unreliable");
//warning: packet size must be large enough for all this
information
                ENetPacket * packet = enet_packet_create
(data, 256, reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
                
                /* if(isServer) enet_host_broadcast (host,
reliable, packet); // alternative: send to all hosts at
once
                else */
                enet_peer_send (peer, reliable, packet); //
queue the packet to be sent to the peer over channel id 0
				free(data);
            }

            //enet_host_flush (host); // not necessary,
included in enet_host_service
        }
        
        // gently terminate connection from client side
after nPacketsMax:
        if(nPacketsMax && peer && !isServer &&
sendCounter>=nPacketsMax) {
            printf("disconnecting after %u sent
packages...\n",nPacketsMax);
            fflush(stdout);
            enet_peer_disconnect (peer, 0);
        }
    } // main loop

    if(peer) {
        printf("resetting peer...");
        fflush(stdout);
        enet_peer_reset (peer);
        printf(" done.\n");
    }
    
    printf("closing down...");
    fflush(stdout);
    enet_host_destroy(host);
    printf(" done.\n");
    return 0;
}



More information about the ENet-discuss mailing list