129 lines
2.7 KiB
C++
129 lines
2.7 KiB
C++
#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 <utility>
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
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<size_t>(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();
|
|
}
|
|
|