[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