PLIB 1.8.5+ r2173 from http://plib.svn.sourceforge.net/svnroot/plib/trunk
This commit is contained in:
354
doc/net/index.html
Normal file
354
doc/net/index.html
Normal file
@@ -0,0 +1,354 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<META name="keywords" content="NET, PLIB, Pegasus, network, library, portable, games, medusa, client, server, socket, TCP, IP, netAddress, netBuffer, netMessage, netGuid, netSocket, netChannel, netBufferChannel, netChat, netMessageChannel, netMonitorServer">
|
||||
<META name="description" content="The Pegasus Network Library is C++ library for making networked games. Pegasus is based on Medusa and it is a part of PLIB. Pegasus, like Medusa, multiplexes I/O with its various client and server connections within a single process/thread. Pegasus is supported on many platforms, including Win32, Linux, and a majority of Unix implementations.">
|
||||
<TITLE>Pegasus Network Library</TITLE>
|
||||
</HEAD>
|
||||
<BODY text="#B5A642" link="#8FFF8F" vlink="#18A515" alink="#20336B"
|
||||
bgcolor="#005000" background="../marble.png">
|
||||
|
||||
<center>
|
||||
<H1>Pegasus Network Library</H1>
|
||||
</center>
|
||||
<H2>Introduction</H2>
|
||||
Pegasus is a C++ library for making networked games. Pegasus is based on
|
||||
<a href="http://www.nightmare.com/medusa/medusa.html">Medusa</a>
|
||||
and is part of <A HREF="../index.html">PLIB</A>.
|
||||
Pegasus, like Medusa, runs as a single process, multiplexing I/O with its various
|
||||
client and server connections within a single process/thread. Pegasus is supported
|
||||
on any platform that includes a socket implementation with the select() function.
|
||||
This includes Win32, Linux, and a majority of Unix implementations.
|
||||
<p>
|
||||
This document assumes a certain degree of knowledge of
|
||||
TCP/IP and socket programming.
|
||||
<p>
|
||||
To use the NET library, you'll need to '#include <plib/net.h>' and
|
||||
link to libplibnet.a
|
||||
<H2>Symbol Conventions.</H2>
|
||||
Pegasus follows the same conventions for symbols and tokens that
|
||||
are used by OpenGL and GLUT. All Pegasus symbols for classes and
|
||||
functions start with <code>net</code> and all <code>#define</code>
|
||||
tokens start with <code>NET</code>. Words within a class or function
|
||||
name are Capitalised and NOT separated with underscores. Words
|
||||
within <code>#define</code> tokens may be separated with underscores
|
||||
to make them readable.
|
||||
<H2>Initialisation.</H2>
|
||||
The first NET call in any program must always be netInit().
|
||||
<H2>Classes</H2>
|
||||
The following class hierarchy makes up the core package - which
|
||||
can be extended to add functionality or to change some underlying
|
||||
mechanisms.
|
||||
<pre>
|
||||
|
||||
class netAddress
|
||||
|
||||
class netBuffer
|
||||
|__ class netMessage
|
||||
|
||||
class netGuid
|
||||
|
||||
class netSocket
|
||||
|__ class netChannel
|
||||
|__ class netBufferChannel
|
||||
| |__ class netChat
|
||||
| |__ class netMessageChannel
|
||||
|
|
||||
|__ class netMonitorServer
|
||||
|
||||
</pre>
|
||||
<H2><code>class netBuffer</code></h2>
|
||||
A simple buffer class.
|
||||
<pre>
|
||||
class netBuffer
|
||||
{
|
||||
public:
|
||||
netBuffer ( int max_length ) ;
|
||||
~netBuffer () ;
|
||||
|
||||
int getLength() const ;
|
||||
int getMaxLength() const ;
|
||||
char* getData() ;
|
||||
|
||||
void remove () ;
|
||||
void remove (int pos, int n) ;
|
||||
bool append (const char* s, int n) ;
|
||||
bool append (int n) ;
|
||||
} ;
|
||||
</pre>
|
||||
<H2><code>class netMessage</code></h2>
|
||||
A message buffer used to transfer binary data and handle byte swapping.
|
||||
<pre>
|
||||
class netMessage : public netBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
netMessage ( const char* s, int n ) ;
|
||||
netMessage ( int type, int to_id, int from_id ) ;
|
||||
|
||||
int getType () const ;
|
||||
int getToID () const ;
|
||||
int getFromID () const ;
|
||||
|
||||
void geta ( void* a, int n ) const ; // a=array; array should already be serialized
|
||||
void puta ( const void* a, int n ) ;
|
||||
|
||||
int getch () const ;
|
||||
void putch ( int c ) ;
|
||||
|
||||
bool getb () const ;
|
||||
void putb ( bool b ) ;
|
||||
|
||||
int getw () const ;
|
||||
void putw ( int i ) ;
|
||||
|
||||
int geti () const ;
|
||||
void puti ( int i ) ;
|
||||
|
||||
void gets ( char* s, int n ) const ;
|
||||
void puts ( const char* s ) ;
|
||||
|
||||
void print ( FILE *fd = stderr ) const ;
|
||||
};
|
||||
</pre>
|
||||
<H2><code>class netAddress</code></h2>
|
||||
This is the representation of an Internet-style machine address.
|
||||
<pre>
|
||||
class netAddress
|
||||
{
|
||||
public:
|
||||
netAddress () ;
|
||||
netAddress ( const char* host, int port ) ;
|
||||
|
||||
void set ( const char* host, int port ) ;
|
||||
|
||||
const char* getHost () const ;
|
||||
int getPort () const ;
|
||||
|
||||
static const char* getLocalHost () ;
|
||||
|
||||
bool getBroadcast () const ;
|
||||
} ;
|
||||
|
||||
</pre>
|
||||
When reading from the network using one of the higher level classes,
|
||||
you can use a netAddress with an empty string as the 'host' to mean
|
||||
"accept data from any host". When writing to the network, the
|
||||
reserved host name '<broadcast>' (the < and > are literally
|
||||
there) will cause the message to be broadcast to all machines on your
|
||||
subnet.
|
||||
<p>
|
||||
Otherwise, use either the machines' network name - or it's IP address
|
||||
(as an ASCII string).
|
||||
<H2><code>class netSocket</code></h2>
|
||||
netSocket is the low-level socket class.
|
||||
<pre>
|
||||
class netSocket
|
||||
{
|
||||
public:
|
||||
netSocket () ;
|
||||
virtual ~netSocket () ;
|
||||
|
||||
int getHandle () const ;
|
||||
void setHandle (int handle) ;
|
||||
|
||||
bool open ( bool stream=true ) ;
|
||||
int bind ( cchar* host, int port ) ;
|
||||
int listen ( int backlog ) ;
|
||||
int accept ( netAddress* addr ) ;
|
||||
int connect ( cchar* host, int port ) ;
|
||||
int send ( const void * buffer, int size, int flags = 0 ) ;
|
||||
int sendto ( const void * buffer, int size, int flags, const netAddress* to ) ;
|
||||
int recv ( void * buffer, int size, int flags = 0 ) ;
|
||||
int recvfrom ( void * buffer, int size, int flags, netAddress* from ) ;
|
||||
void close ( void ) ;
|
||||
void setBlocking ( bool blocking ) ;
|
||||
} ;
|
||||
</pre>
|
||||
<H3>Example:</H3>
|
||||
This example is stripped of error checking for clarity:
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD>
|
||||
<H4>Sender:</H4>
|
||||
<pre>
|
||||
netInit () ;
|
||||
|
||||
netSocket *sock = new netSocket () ;
|
||||
sock -> open ( false ) ;
|
||||
sock -> setBlocking ( false ) ;
|
||||
sock -> connect ( host, port ) ;
|
||||
|
||||
while ( !done )
|
||||
sock -> send ( msg, len, 0 );
|
||||
|
||||
sock -> close () ;
|
||||
</pre>
|
||||
</TD>
|
||||
<TD>
|
||||
<H4>Reciever:</H4>
|
||||
<pre>
|
||||
netInit () ;
|
||||
|
||||
netSocket *sock = new netSocket () ;
|
||||
sock -> open ( false ) ;
|
||||
sock -> setBlocking ( false ) ;
|
||||
sock -> bind ( host, port ) ;
|
||||
|
||||
while ( !done )
|
||||
if ( (len = sock -> recv(msg, maxlen, 0)) >= 0 )
|
||||
...use the data...
|
||||
|
||||
sock -> close () ;
|
||||
</pre>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
This code produces a 'Datagram' connection - which is fast but unreliable
|
||||
(using UDP protocol). Passing a 'true' to sock->open() would produce a
|
||||
'Stream' connection (using TCP).
|
||||
|
||||
<H2><code>class netChannel</code></h2>
|
||||
netChannel adds event-handling to the low-level
|
||||
netSocket class. Otherwise, it can be treated as
|
||||
a normal non-blocking socket object.
|
||||
The direct interface between the poll loop and
|
||||
the channel object are the handleReadEvent and
|
||||
handleWriteEvent methods. These are called
|
||||
whenever a channel object 'fires' that event.
|
||||
The firing of these low-level events can tell us whether
|
||||
certain higher-level events have taken place, depending on
|
||||
the timing and state of the connection.
|
||||
<pre>
|
||||
class netChannel : public netSocket
|
||||
{
|
||||
public:
|
||||
|
||||
netChannel () ;
|
||||
virtual ~netChannel () ;
|
||||
|
||||
void setHandle (int s, bool is_connected = true);
|
||||
bool isConnected () const ;
|
||||
bool isClosed () const ;
|
||||
void shouldDelete () ;
|
||||
|
||||
// --------------------------------------------------
|
||||
// socket methods
|
||||
// --------------------------------------------------
|
||||
|
||||
bool open ( bool stream=true ) ;
|
||||
int listen ( int backlog ) ;
|
||||
int connect ( cchar* host, int port ) ;
|
||||
int send ( const void * buf, int size, int flags = 0 ) ;
|
||||
int recv ( void * buf, int size, int flags = 0 ) ;
|
||||
void close ( void ) ;
|
||||
|
||||
// poll() eligibility predicates
|
||||
virtual bool readable (void) ;
|
||||
virtual bool writable (void) ;
|
||||
|
||||
// --------------------------------------------------
|
||||
// event handlers
|
||||
// --------------------------------------------------
|
||||
|
||||
void handleReadEvent (void);
|
||||
void handleWriteEvent (void);
|
||||
|
||||
// These are meant to be overridden.
|
||||
virtual void handleConnect (void) ;
|
||||
virtual void handleRead (void) ;
|
||||
virtual void handleWrite (void) ;
|
||||
virtual void handleClose (void) ;
|
||||
virtual void handleAccept (void) ;
|
||||
virtual void handleError (int error) ;
|
||||
|
||||
static bool poll (u32 timeout = 0 ) ;
|
||||
static void loop (u32 timeout = 0 ) ;
|
||||
};
|
||||
</pre>
|
||||
<H2><code>class netBufferChannel</code></h2>
|
||||
netBufferChannel is a netChannel with I/O buffering.
|
||||
Clients and servers built on top of netBufferChannel
|
||||
automatically support pipelining where you can send
|
||||
multiple commands without waiting for the response
|
||||
to each command before you send the next.
|
||||
<pre>
|
||||
class netBufferChannel : public netChannel
|
||||
{
|
||||
public:
|
||||
netBufferChannel (int in_buffer_size = 512, int out_buffer_size = 4096) ;
|
||||
void closeWhenDone (void) ;
|
||||
|
||||
virtual bool bufferSend (const char* msg, int msg_len) ;
|
||||
virtual void handleBufferRead (netBuffer& buffer) ;
|
||||
};
|
||||
</pre>
|
||||
<H2><code>class netChat</code></h2>
|
||||
netChat adds support for 'chat' style protocols -
|
||||
where one side sends a 'command', and the other sends
|
||||
a response (examples would be the common internet
|
||||
protocols - smtp, nntp, ftp, etc..).
|
||||
<p>
|
||||
The handle_buffer_read() method looks at the input
|
||||
stream for the current 'terminator' (usually '\r\n'
|
||||
for single-line responses, '\r\n.\r\n' for multi-line
|
||||
<pre>
|
||||
class netChat : public netBufferChannel
|
||||
{
|
||||
public:
|
||||
netChat () ;
|
||||
|
||||
void setTerminator (const char* t);
|
||||
const char* getTerminator (void);
|
||||
|
||||
bool push (const char* s) ;
|
||||
|
||||
virtual void collectIncomingData (const char* s, int n) ;
|
||||
virtual void foundTerminator (void) ;
|
||||
};
|
||||
</pre>
|
||||
<H2><code>class netMessageChannel</code></h2>
|
||||
A channel for binary messages. Takes care of packing and unpacking them in/out of the buffers.
|
||||
<pre>
|
||||
class netMessageChannel : public netBufferChannel
|
||||
{
|
||||
public:
|
||||
netMessageChannel () ;
|
||||
|
||||
bool sendMessage ( const netMessage& msg ) ;
|
||||
virtual void handleMessage ( const netMessage& msg ) ;
|
||||
};
|
||||
</pre>
|
||||
<H2><code>class netMonitorServer</code></h2>
|
||||
The monitor server gives you remote, 'back-door' access to your server while it is running. netMonitor is a telnet command port with
|
||||
password authorization. It can be paired with and used to remotely admin another server.
|
||||
Once connected via any telnet client to the monitor, you can issue commands. The monitor can be hooked up to a python interpreter for added power. Since an ordinary telnet session is not secure, the password could be intercepted, but that level of security is usually not needed for games.
|
||||
<pre>
|
||||
class netMonitorServer : public netChannel
|
||||
{
|
||||
public:
|
||||
netMonitorServer( cchar* _name, int port ) ;
|
||||
~netMonitorServer() ;
|
||||
|
||||
cchar* getPassword () const ;
|
||||
void setPassword ( cchar* string ) ;
|
||||
void setPrompt ( cchar* string ) ;
|
||||
void setCommandFunc ( void (*func)(cchar*, netMonitorChannel*) ) ;
|
||||
} ;
|
||||
</pre>
|
||||
<hr>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="http://validator.w3.org/check/referer"><img border="0" src="../valid-html40.png" alt="Valid HTML 4.0!" height="31" width="88"></a>
|
||||
<td>
|
||||
<ADDRESS>
|
||||
<A HREF="http://mcdave.cjb.net">
|
||||
Dave McClurg</A>
|
||||
<<A HREF="mailto:dpm@efn.org">dpm@efn.org</A>>
|
||||
</ADDRESS>
|
||||
</table>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
Reference in New Issue
Block a user