00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef NETWORK_HAS_BEEN_INCLUDED
00010 #define NETWORK_HAS_BEEN_INCLUDED
00011
00012 #include "std/platform.H"
00013
00014 #ifdef WIN32
00015 #define ssize_t int
00016 #include <winsock.h>
00017 #include <io.h>
00018 #else
00019 #include <sys/socket.h>
00020 #include <netinet/in.h>
00021 #include <arpa/inet.h>
00022 #include <netdb.h>
00023 #endif
00024
00025 #include "std/support.H"
00026 #include "mem_push.H"
00027 #include "stream.H"
00028 #include "dev/tty.H"
00029
00030 enum NETenum {
00031 NETadd_connection,
00032 NETquit,
00033 NETtext,
00034 NETflush,
00035 NETcontext,
00036 NETidentify,
00037 NETbroadcast,
00038 NETbarrier,
00039 NETswap_ack
00040 };
00041
00042 class Network;
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class NetStream : public STDdstream, public FD_EVENT {
00055 friend class Network;
00056 public:
00057 enum StreamFlags {
00058 write = 0x1,
00059 read = 0x2,
00060 rw = 0x3,
00061 ascii = 0x4,
00062 ascii_w = 0x5,
00063 ascii_r = 0x6,
00064 ascii_rw = 0x7
00065 };
00066
00067 NetStream (int port, const char *name);
00068 NetStream (int fd, struct sockaddr_in *client,bool block=false);
00069 NetStream (Cstr_ptr &name, StreamFlags);
00070 virtual ~NetStream();
00071
00072 str_ptr name (void) const { return name_; }
00073 str_ptr print_name (void) const { return print_name_; }
00074 int port (void) const { return port_; }
00075 int processing (void) const { return processing_; }
00076 Network* network (void) const { return network_; }
00077 void subscribe (Cstr_ptr &t){ tags_ += t; }
00078 void subscribe (Cstr_list &t){ tags_ = t; }
00079
00080 bool attached (void) const { return (!!iostr()) || (_fd != -1); }
00081
00082 void set_port (int p);
00083 void add_network(Network *n) { network_ = n; }
00084 void flush_data (void);
00085 int read_stuff (void);
00086
00087 virtual void sample();
00088
00089
00090 void no_tcp_delay();
00091
00092 static void no_linger(int fd);
00093
00094 protected:
00095 void set_blocking(bool val) const;
00096 ssize_t write_to_net (const void *buf, size_t nbyte) const;
00097 ssize_t read_from_net( void *buf, size_t nbyte) const;
00098 int interpret (void);
00099 virtual size_t recv(UGAptr, int)
00100 { cerr << "NetStream: recv unimplemented\n"; return 0; }
00101 virtual size_t send(const UGAptr data, int count)
00102 { return write_to_net((const void *)data, (size_t)count); }
00103 void remove_me();
00104
00105 private:
00106
00107 void _die(const char *msg);
00108
00109 str_list tags_;
00110 str_ptr name_;
00111 int port_;
00112 int msgSize_;
00113 int processing_;
00114 str_ptr print_name_;
00115 Network *network_;
00116 };
00117
00118
00119 class Network_obs
00120 {
00121 public:
00122 enum event {accept_str=0, remove_str};
00123
00124 virtual ~Network_obs() {}
00125 Network_obs() {}
00126
00127 virtual void notify_net( const event &e, NetStream *s ) = 0;
00128 };
00129
00130
00131
00132 class Network: public FD_EVENT {
00133 friend class NetStream;
00134 static int NETWORK_SERVER_BACKLOG;
00135
00136 protected:
00137 FD_MANAGER *_manager;
00138 int nStreams_;
00139 NetStream *streams_[256];
00140 str_list tags_;
00141 int port_;
00142 str_ptr name_;
00143 int first_;
00144
00145 virtual void sample () { accept_stream(); }
00146 virtual void Unregister(NetStream *s) { _manager->rem(s); }
00147 virtual void Register (NetStream *s) { _manager->add(s);
00148 s->add_network(this); }
00149 virtual void Register () { _manager->add(this); }
00150 virtual int interpret (NETenum code, NetStream *sender) = 0;
00151 virtual void add_client(NetStream *cli);
00152 virtual void remove_stream(NetStream *s);
00153
00154 void _die (const char *msg);
00155 char *configure (int port, int backlog = NETWORK_SERVER_BACKLOG);
00156 void add_stream(NetStream *s) { Register(streams_[nStreams_++]=s);
00157 s->subscribe(tags_); }
00158 virtual void accept_stream(void);
00159 NetStream *wait_for_connect();
00160
00161 ARRAY<Network_obs *> _obs_list;
00162 int _at_barrier;
00163
00164 public:
00165 Network(FD_MANAGER *m) : _manager(m), nStreams_(0),name_(""),
00166 _at_barrier(0) { }
00167 virtual ~Network() {}
00168
00169 void connect_to (NetStream *s);
00170 void start ( int port=0);
00171 void start (char *host,int port) { start();
00172 connect_to(new NetStream(port,host)); }
00173 void flush_data ();
00174
00175 void subscribe (Cstr_ptr &tag) { tags_ += tag;
00176 for (int i=0; i < nStreams_; i++)
00177 streams_[i]->subscribe(tag); }
00178 NetStream *operator[] (int i) { return streams_[i]; }
00179 int num_streams(void) const { return nStreams_; }
00180 int port (void) const { return port_; }
00181 Cstr_ptr &name (void) const { return name_; }
00182 int processing (void) const;
00183
00184 #undef barrier
00185 void barrier ();
00186 void add_net_obs(Network_obs *o) { _obs_list += o; }
00187 void rem_net_obs(Network_obs *o) { _obs_list -= o; }
00188 void notify_net (Network_obs::event e,
00189 NetStream *s) { for(int i=0;i<_obs_list.num();i++)
00190 _obs_list[i]->notify_net(e,s); }
00191 };
00192
00193
00194 STDdstream & operator >> (STDdstream &, NETenum &);
00195 STDdstream & operator << (STDdstream &, NETenum );
00196
00197 template <class T>
00198 inline Network &
00199 operator << (Network &n, const T &d) {
00200 for (int i=0; i<n.num_streams(); i++)
00201 *((STDdstream *)n[i]) << d;
00202 return n;
00203 }
00204
00205 #ifdef WIN32
00206 ssize_t write_win32(int fildes, const void *buf, size_t nbyte);
00207 ssize_t read_win32 (int fildes, void *buf, size_t nbyte);
00208 int num_bytes_to_read(int fildes);
00209 #else
00210 int num_bytes_to_read(int fildes);
00211 #endif
00212
00213 #endif