-e HTTP/1.0 200 OK -e /** * File: expensive-server.cc * ------------------------- * Illustrates how nonblocking IO can be used to implement * a single-threaded web server. This particular example wastes * a huge amount of CPU time (as it while loops forever without * blocking), but it does demonstrate how nonblocking IO can * be used to very easily serve multiple client requests as a * time without threads or multiple processes. */ #include "outbound-file.h" #include "server-socket.h" #include "non-blocking-utils.h" #include // for accept #include #include #include using namespace std; static const unsigned short kDefaultPort = 12345; static const string kFileToServe("expensive-server.cc.html"); int main(int argc, char **argv) { int serverSocket = createServerSocket(kDefaultPort); if (serverSocket == kServerSocketFailure) { cerr << "Could not start server. Port " << kDefaultPort << " is probably in use." << endl; return 0; } setAsNonBlocking(serverSocket); cout << "Static file server listening on port " << kDefaultPort << "." << endl; list outboundFiles; size_t numConnections = 0; size_t numActiveConnections = 0; size_t numAcceptCalls = 0; while (true) { int clientSocket = accept(serverSocket, NULL, NULL); cout << "Num calls to accept: " << ++numAcceptCalls << "." << endl; if (clientSocket == -1) { assert(errno == EWOULDBLOCK); } else { OutboundFile obf; obf.initialize(kFileToServe, clientSocket); outboundFiles.push_back(obf); cout << "Connection #" << ++numConnections << endl; cout << "Queue size: " << ++numActiveConnections << endl; } auto iter = outboundFiles.begin(); while (iter != outboundFiles.end()) { if (iter->sendMoreData()) { ++iter; } else { iter = outboundFiles.erase(iter); cout << "Queue size: " << --numActiveConnections << endl; } } } }