00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <stdio.h>
00038
00039 #include <exception>
00040 #include <string>
00041
00042 #include <FileDescriptor.h>
00043 #include <SocketDescriptor.h>
00044
00045 #include <mps/mps.h>
00046
00047 typedef map< int, ref<FileDescriptor> > outputMap_t;
00048 static outputMap_t outputs;
00049
00050
00051
00052 class ReadCallback: public FileDescriptor::Callback {
00053 public:
00054 string readLine(ref<FileDescriptor> const &desc) {
00055 string inputLine;
00056 int ch;
00057
00058 while (desc->read(ch) && ch != '\n') {
00059 if (ch != '\r')
00060 inputLine.append(1, (char) ch);
00061 }
00062
00063 return inputLine;
00064 }
00065
00066 void sendToAll(string line) {
00067 for (outputMap_t::iterator i = outputs.begin();
00068 i != outputs.end();
00069 i++) {
00070 (*i).second->write(line.data(), line.size());
00071 }
00072 }
00073
00074 void readHandler(ref<FileDescriptor> const &desc) {
00075 try {
00076 string inputLine = readLine(desc);
00077 fprintf(stderr, "Read line '%s' from fd %d\n", inputLine.c_str(), desc->getFd());
00078
00079 if (inputLine == "quit") {
00080 fprintf(stderr, "Received quit request on fd %d\n", desc->getFd());
00081 outputs.erase(outputs.find(desc->getFd()));
00082 desc->close();
00083 } else {
00084 char fdcount[20];
00085 sprintf(fdcount, "%d/%d", desc->getFd(), desc->getFdMgr()->getCountRegistered());
00086
00087 string outputLine = ">>> " + string(fdcount) + ": " + inputLine + "\r\n";
00088 sendToAll(outputLine);
00089 }
00090 } catch (FileDescriptor::Exception &e) {
00091 fprintf(stderr, "Exception in readHandler: %s (%d: %s)\n",
00092 e.what(),
00093 e.getErrno(), strerror(e.getErrno()));
00094 outputs.erase(outputs.find(desc->getFd()));
00095 desc->close();
00096 }
00097 }
00098 };
00099
00100
00101
00102 class AcceptCallback: public FileDescriptor::Callback {
00103 private:
00104 ref<FileDescriptorManager> fdmgr;
00105 ref<ServerSocketDescriptor> server;
00106
00107 public:
00108 AcceptCallback(ref<FileDescriptorManager> const &_fdmgr,
00109 ref<ServerSocketDescriptor> const &_server)
00110 : fdmgr(_fdmgr),
00111 server(_server)
00112 {}
00113
00114 void acceptHandler(ref<FileDescriptor> const &desc) {
00115 if (desc.get() != server.get())
00116 throw FileDescriptor::Exception("Bloody hell! Unmatched FileDescriptor object!");
00117
00118 ref<SocketDescriptor> sock = server->accept();
00119 fprintf(stderr, "Accepted new connection on fd %d\n", sock->getFd());
00120 outputs[sock->getFd()] = sock;
00121
00122 sock->setReadCallback(new ReadCallback(),
00123 (FileDescriptor::Callback::Method) &ReadCallback::readHandler);
00124 }
00125 };
00126
00127
00128
00129 static void doServer() {
00130 ref<FileDescriptorManager> fdmgr = new FileDescriptorManager();
00131 ref<ServerSocketDescriptor> server = new ServerSocketDescriptor(fdmgr);
00132
00133 fprintf(stderr, "Canonical address: %s\n", server->getCanonicalAddress().c_str());
00134
00135 ref<AcceptCallback> cb = new AcceptCallback(fdmgr, server);
00136 server->setReadCallback(cb, (FileDescriptor::Callback::Method) &AcceptCallback::acceptHandler);
00137
00138 fdmgr->mainloop();
00139 }
00140
00141
00142
00143 static void doClient() {
00144 fprintf(stderr, "Unimplemented stub at the moment.\n");
00145 }
00146
00147 int main(int argc, char *argv[]) {
00148 if (argc < 2) {
00149 fprintf(stderr,
00150 "Usage: testChassis <cmdType>\n"
00151 " where cmdType is one of -\n"
00152 " server\n"
00153 " client\n");
00154 exit(1);
00155 }
00156
00157 string cmdType = argv[1];
00158
00159 try {
00160 if (cmdType == "server") {
00161 doServer();
00162 } else if (cmdType == "client") {
00163 doClient();
00164 } else {
00165 fprintf(stderr, "Unknown cmdType %s\n", cmdType.c_str());
00166 exit(1);
00167 }
00168 } catch (exception &e) {
00169 fprintf(stderr, "Straight std::exception: %s\n", e.what());
00170 } catch (MPS::MPSException &mpse) {
00171 fprintf(stderr, "MPSException: %s\n", mpse.getMessage().c_str());
00172 } catch (...) {
00173 fprintf(stderr, "Unknown exception!\n");
00174 }
00175
00176 return 0;
00177 }