#include "examples/sudoku/sudoku.h" #include "muduo/base/Atomic.h" #include "muduo/base/Logging.h" #include "muduo/base/Thread.h" #include "muduo/net/EventLoop.h" #include "muduo/net/InetAddress.h" #include "muduo/net/TcpServer.h" #include #include #include using namespace muduo; using namespace muduo::net; class SudokuServer { public: SudokuServer(EventLoop* loop, const InetAddress& listenAddr) : server_(loop, listenAddr, "SudokuServer"), startTime_(Timestamp::now()) { server_.setConnectionCallback( std::bind(&SudokuServer::onConnection, this, _1)); server_.setMessageCallback( std::bind(&SudokuServer::onMessage, this, _1, _2, _3)); } void start() { server_.start(); } private: void onConnection(const TcpConnectionPtr& conn) { LOG_TRACE << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " is " << (conn->connected() ? "UP" : "DOWN"); } void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) { LOG_DEBUG << conn->name(); size_t len = buf->readableBytes(); while (len >= kCells + 2) { const char* crlf = buf->findCRLF(); if (crlf) { string request(buf->peek(), crlf); buf->retrieveUntil(crlf + 2); len = buf->readableBytes(); if (!processRequest(conn, request)) { conn->send("Bad Request!\r\n"); conn->shutdown(); break; } } else if (len > 100) // id + ":" + kCells + "\r\n" { conn->send("Id too long!\r\n"); conn->shutdown(); break; } else { break; } } } bool processRequest(const TcpConnectionPtr& conn, const string& request) { string id; string puzzle; bool goodRequest = true; string::const_iterator colon = find(request.begin(), request.end(), ':'); if (colon != request.end()) { id.assign(request.begin(), colon); puzzle.assign(colon+1, request.end()); } else { puzzle = request; } if (puzzle.size() == implicit_cast(kCells)) { LOG_DEBUG << conn->name(); string result = solveSudoku(puzzle); if (id.empty()) { conn->send(result+"\r\n"); } else { conn->send(id+":"+result+"\r\n"); } } else { goodRequest = false; } return goodRequest; } TcpServer server_; Timestamp startTime_; }; int main(int argc, char* argv[]) { LOG_INFO << "pid = " << getpid() << ", tid = " << CurrentThread::tid(); EventLoop loop; InetAddress listenAddr(9981); SudokuServer server(&loop, listenAddr); server.start(); loop.loop(); }