1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/*
* Atom-4 Network Protocol utility functions
* Header file
*
* $Id: net.h,v 1.8 2003/04/14 20:57:22 hsteoh Exp hsteoh $
*/
#ifndef NET_H
#define NET_H
#include <stdarg.h>
#include <stdlib.h> // for size_t
#include <dlist.h> // MUST be prog/lib version!
#include "event.h"
#define NET_LINE_LIMIT 1024 // as recommended by protocol
#define NET_BUFFER_SIZE ((NET_LINE_LIMIT)+1)
// A network message parser. This class is mainly for providing convenience
// message parsing functions.
class netparser {
char *raw; // [R]
int rlen; // length of *raw
char *type; // [R] first word of packet
int curpos; // current position in buffer
void skip_spaces();
public:
netparser(char *message=NULL); // [R] *message MUST be null-terminated
~netparser();
// Begin parsing a new message. Note that *message will be ALTERED as part
// of the parsing process. The caller is responsible for saving a copy of
// the original message if needed.
void parse(char *message);
// Abort parsing of current message, and reset parser state
void reset();
// Returns first word in packet. NULL if there is no word in packet.
// Note that this does *not* consume any characters from the buffer.
char *packet_type() { return type; } // [R]
// Calling this multiple times will retrieve individual arguments in the
// packet.
// - the first word in the packet is NEVER returned by this function;
// use packet_type() instead. The first word returned is always the
// first argument (i.e. second word in packet)
// - Returns the empty string if there are no more arguments in the packet.
char *next_word(); // [R]()
// Returns the remainder of the packet. Note that this will consume all
// remaining characters in packet. Returns NULL if there are no more
// arguments left in the packet.
char *get_rest();
};
// A generic network connection.
//
// Currently, this class implements line length limits and truncation as
// described in the protocol.
class netconn : public eventhandler {
eventloop *loop; // [R]
int sock; // network socket
int sendlimit; // max queued outgoing packets before
// exception is thrown
char rcvbuf[NET_BUFFER_SIZE]; // network buffer (circular buffer)
size_t rcvbuf_end; // index of first free byte in buffer
odlist<char> sendqueue; // outgoing packets waiting for
// write-ready condition on socket
int truncate:1; // 1 if in truncate mode, 0 otherwise
void scan_for_packets(); // scan buffer for completed packets
void wrap_buffer(int start); // shift buffer contents (start) bytes
// backwards.
protected:
// Conditions to be handled by derived class:
// - process_packet() is called every time a completed packet is available
// - disconnected() is called when we detect that the socket has been
// disconnected prematurely. The derived class should immediately
// trigger a cleanup process to remove this connection from the pool.
virtual void process_packet(char *packet)=0;
virtual void disconnected()=0;
public:
netconn(int sock, eventloop *loop, int sendqueue_limit);
virtual ~netconn();
// Queue packet for sending
int send_packet(char *fmt, ...);
int vsend_packet(char *fmt, va_list args);
// Access functions
int sockfd() { return sock; }
// Pure virtuals overridden from base class
virtual void read_ready(eventloop *src, int fd);
virtual void write_ready(eventloop *src, int fd);
// Force sending of all queued outgoing packets. By default, send_packet()
// only queues packets for sending, and waits until a write_ready() before
// actually sending data into the socket. This function forces all pending
// packets to be written into the socket.
// NOTE: this function may block.
void flush();
};
#endif // NET_H
|