87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
#ifndef NetConnection_included
|
|
#define NetConnection_included
|
|
|
|
#include "Boolean.h"
|
|
|
|
// NetConnection is an abstract base class that implements an event
|
|
// driven, flow controlled reliable datagram connection over an
|
|
// already open stream socket.
|
|
//
|
|
// The incoming and outgoing data streams are broken into messages.
|
|
// The format of a message is four bytes of message length (MSB
|
|
// first) followed by "length" bytes of data. The last byte of data
|
|
// should be NUL ('\0'). The maximum message length is determined by
|
|
// the buffer sizes passed to the NetConnection constructor.
|
|
//
|
|
// The mprintf() function outputs a message using printf-style
|
|
// formatting. It appends a NUL byte to the message and prepends the
|
|
// message length. It also automatically flushes the message. If
|
|
// the connection has closed, mprintf() returns immediately.
|
|
//
|
|
// When a complete message is received, the pure virtual function
|
|
// input_msg() is called with the length and the address of the
|
|
// message. If EOF is read on the connection, input_msg() is called
|
|
// with a NULL address and count (analogously to read(2) returning 0
|
|
// bytes).
|
|
//
|
|
// NetConnection implements flow control. Whenever the output buffer
|
|
// is empty, read events are accepted from the Scheduler. Whenever
|
|
// the output buffer can't be flushed, reading is suspended, and the
|
|
// Scheduler watches for the connection to be writable. This means
|
|
// that input is only accepted when it's possible to send a reply.
|
|
// The unblock handler, if any, is called whenever output becomes
|
|
// unblocked.
|
|
|
|
class NetConnection {
|
|
|
|
public:
|
|
|
|
typedef void (*UnblockHandler)(void *closure);
|
|
|
|
NetConnection(int fd,
|
|
char *inbuf, unsigned isize,
|
|
char *outbuf, unsigned osize,
|
|
UnblockHandler, void *closure);
|
|
|
|
virtual ~NetConnection();
|
|
Boolean ready_for_output() const { return oready; }
|
|
void ready_for_input(Boolean);
|
|
|
|
protected:
|
|
|
|
virtual void input_msg(const char *data, unsigned nbytes) = 0;
|
|
void mprintf(const char *format, ...);
|
|
|
|
private:
|
|
|
|
typedef unsigned int Length;
|
|
|
|
int fd;
|
|
Boolean iready, oready;
|
|
char *ibuf, *obuf;
|
|
char *iend, *oend;
|
|
char *itail, *otail;
|
|
UnblockHandler unblock_handler;
|
|
void *closure;
|
|
|
|
void set_handlers(Boolean new_iready, Boolean new_oready);
|
|
void shutdown(Boolean = true);
|
|
|
|
// Input
|
|
|
|
void input();
|
|
void deliver_input();
|
|
static void read_handler(int fd, void *closure);
|
|
|
|
// Output
|
|
|
|
void flush();
|
|
static void write_handler(int fd, void *closure);
|
|
|
|
NetConnection(const NetConnection&); // Do not copy
|
|
operator = (const NetConnection&); // or assign.
|
|
|
|
};
|
|
|
|
#endif /* !NetConnection_included */
|