00001
00002 #ifndef _TCPSERVER_H__
00003 #define _TCPSERVER_H__
00004
00005 #include <map>
00006 #include <iostream>
00007
00008 #include <netinet/in.h>
00009 #include <gea/posix/UnixFdHandle.h>
00010 #include <gea/Time.h>
00011
00012 namespace awds {
00013 class TcpConnection {
00014 std::string peer;
00015 gea::UnixFdHandle *fdHdl;
00016
00017 static void read_client_data(gea::Handle *h, gea::AbsTime t, void *data);
00018 public:
00019 int fd;
00020
00021 TcpConnection(int fd, gea::UnixFdHandle *fdHdl, std::string &peer) :
00022 fd(fd),
00023 fdHdl(fdHdl),
00024 peer(peer)
00025 {}
00026 TcpConnection(int fd, std::string &peer) {
00027 TcpConnection(fd, new gea::UnixFdHandle(fd, gea::PosixModeRead), peer);
00028 }
00029 TcpConnection(int fd, struct sockaddr_in6 &peer);
00030
00031 TcpConnection() : fd(-1) {}
00032
00033 typedef void (TcpConnCallback)(TcpConnection &cl, const char *data, size_t datalen, void *cookie);
00034
00035 int write(uint8_t *data, ssize_t datalen) {
00036 return fdHdl->write((char*)data, datalen);
00037 }
00038 void close() {
00039 if (fd >= 0) {
00040 ::close(fd);
00041 delete fdHdl;
00042 }
00043 }
00044
00045 friend std::ostream& operator<<(std::ostream &s, const TcpConnection &c) {
00046 return s << c.peer;
00047 }
00048
00049 void waitForData(TcpConnCallback *on_recv, TcpConnCallback *on_error, void *cookie);
00050 private:
00051 TcpConnCallback *recv_cb, *error_cb;
00052 void *cb_cookie;
00053 };
00054
00059 class TcpServer {
00060 protected:
00061 const char *name;
00062 unsigned short port;
00063 int lsock;
00064 gea::UnixFdHandle *lsockHdl;
00065
00066 bool createSocket();
00067 static void accept_connection(gea::Handle *h, gea::AbsTime t, void *data);
00068
00069 public:
00070 typedef void (AcceptCallback)(int client_fd, struct sockaddr_in6 &peer, void *cookie);
00071
00072 TcpServer(const char *servicename, unsigned short listenport);
00073
00074 virtual bool start();
00075
00076 void waitForClient(AcceptCallback *cb, void *cookie);
00077 private:
00078 AcceptCallback *a_cb;
00079 void *a_cookie;
00080 };
00081
00082 class TcpBroadcast : TcpServer {
00083 typedef std::map<int, TcpConnection> ClientList;
00084 ClientList clients;
00085
00086 ClientList::iterator findHandle(gea::Handle *h);
00087
00088
00089
00090 static void new_client(int client_fd, struct sockaddr_in6 &peer, void *cookie);
00091 static void client_recv(TcpConnection &cl, const char *data, size_t datalen, void *cookie);
00092 static void client_error(TcpConnection &cl, const char *data, size_t datalen, void *cookie);
00093 public:
00094 TcpBroadcast(const char* servicename, unsigned short listenport) :
00095 TcpServer(servicename, listenport)
00096 {}
00097
00098 virtual bool start() {
00099 if (TcpServer::start()) {
00100 waitForClient(new_client, this);
00101 return true;
00102 } else return false;
00103 }
00104
00105 void send_to_all(const char *data, size_t datalen);
00106 void terminate(int fd);
00107 };
00108 }
00109
00110 #endif // _TCPSERVER_H__
00111
00112
00113
00114
00115
00116
00117