[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