Posted by Andy on January 26, 2006 at 05:08:50:
Hi there. I've written a quick and dirty server app using HawkNL, mostly by hacking up the client/server example. It runs fine and accepts input from my client app as long as both are run on Linux. When I run the server the on Windows it gets as far as readng the packet sent to it but nlRead returns -1 as if it couldn't read anything.
I'm not normally a fan of pasting a big gob of code to a forum but its probably all relevant.
#include
#include
// include the network library functionality
#include "nl.h"
// do cross platform magic
// we need windows.h under windows and unistd.h in a linux environment
#if defined WIN32 || defined WIN64
#define WIN32_LEAN_AND_MEAN
#include
#define sleep(x) Sleep( 1000 * (x) )
#else
#include
#endif
// the port the server is going to listen on
#define SERVER_PORT 3333
// the maximum number of clients we can cope with
// the underlying network library will break above this
// but we don't expect many cases of needing multiple
// connections at the same time
#define MAX_CLIENTS 8
// the size of our data buffer for reading network data
#define BUFFER_SIZE 128
// channel to allow threads to be told to finish
bool done = false;
// hawknl standard error exit function (use and abuse for debugging)
void PrintErrorExit( void ) {
// get the error thats just happened
NLenum err = nlGetError();
// see if we've had a system error or a hawknl one
if ( err == NL_SYSTEM_ERROR ) {
printf( "System error: %s\n", nlGetSystemErrorStr( nlGetSystemError() ) );
} else {
printf( "HawkNL error: %s\n", nlGetErrorStr( err ) );
}
// clean up before exit
nlShutdown();
// don't let MSVC bail
getchar();
// goodbye
exit(1);
}
// server loop, process the information we're sent by the client
// since we just want to pass out information from the client and
// display info in a GUI we won't actually need to talk back
void *ServerLoop( void *sockIn ) {
// we've passed the socket in as a parameter so we need to cast it
NLsocket sock = *(NLsocket *)sockIn;
// hawknl group object for tracking connections
NLint group = nlGroupCreate();
// keep looping until we get a quit message
// (nasty hacky global variable channel)
while ( !done ) {
// socket that we'll be talking to
NLsocket newsock;
// see if there is a new socket connection waiting
newsock = nlAcceptConnection( sock );
// if there is a socket connection waiting deal with it
// otherwise see if an error occured or if there was just
// no connection waiting
if ( newsock != NL_INVALID ) {
// add the new socket to our manager
nlGroupAddSocket( group, newsock );
} else {
// grab the error
NLint err = nlGetError();
// see what type it is
if ( err == NL_SYSTEM_ERROR || err == NL_NOT_LISTEN ) {
PrintErrorExit();
}
}
// the sockets that need to be read from
NLsocket readSocks[MAX_CLIENTS];
// check the group to see if it has anything for us
int count = nlPollGroup( group, NL_READ_STATUS, readSocks, MAX_CLIENTS, 0 );
// check for errors
if ( count == NL_INVALID ) {
PrintErrorExit();
}
// see if any sockets want reading from
// clearly this loop won't run if count == 0
for ( int i = 0; i 0 ) {
// make sure its null terminated
buffer[readlen] = 0;
printf( "socket %d :: %s\n", i, buffer);
}
// check for socket closure
if ( readlen == NL_INVALID ) {
NLenum err = nlGetError();
PrintErrorExit();
if ( err == NL_MESSAGE_END || err == NL_SOCK_DISCONNECT ) {
nlGroupDeleteSocket( group, readSocks[i]);
nlClose( readSocks[i] );
}
}
}
// mmm nap time
nlThreadYield();
}
// we're done so return so the program can quit
return 0;
}
// entry point
int main( int argc, char **argv ) {
// setup hawknl
if ( !nlInit() ) {
PrintErrorExit();
}
// select the network type (we only ever use IP for this)
if ( !nlSelectNetwork( NL_IP ) ) {
PrintErrorExit();
}
// setup the server socket we're going to play with
// we open it on the port #defined at the top and use mode
// NL_RELIABLE_PACKETS so we don't have to mess with streams
// but we guarantee to get what we send in the right order
NLsocket serversock = nlOpen( SERVER_PORT, NL_RELIABLE_PACKETS );
// make sure the socket opened as expected
if ( serversock == NL_INVALID ) {
nlClose( serversock );
PrintErrorExit();
}
// start listening (or die if we can't)
if ( !nlListen( serversock ) ) {
nlClose( serversock );
PrintErrorExit();
}
// now everything is setup we can launch the networking thread
// as a demo app its not necessary for it to sit in a thread
// but it may as well so the GUI doesn't cry when we add one
NLthreadID id = nlThreadCreate( ServerLoop, (void *)&serversock, NL_TRUE );
// hang around until the thread quits
// make sure this gets removed in the GUI version as the thread
// won't quit until its told to
nlThreadJoin( id, NULL );
// clean up the server socket resources
// complete with error checking incase something crazy happened
if ( !nlClose( serversock ) ) {
PrintErrorExit();
}
// clean up the networking library
nlShutdown();
// done
return 0;
}