├── .vscode └── settings.json ├── README.md ├── code ├── day01 │ ├── Makefile │ ├── client.cpp │ └── server.cpp ├── day02 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ ├── util.cpp │ └── util.h ├── day03 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ ├── util.cpp │ └── util.h ├── day04 │ ├── Epoll.cpp │ ├── Epoll.h │ ├── InetAddress.cpp │ ├── InetAddress.h │ ├── Makefile │ ├── Socket.cpp │ ├── Socket.h │ ├── client.cpp │ ├── server.cpp │ ├── util.cpp │ └── util.h ├── day05 │ ├── Channel.cpp │ ├── Channel.h │ ├── Epoll.cpp │ ├── Epoll.h │ ├── InetAddress.cpp │ ├── InetAddress.h │ ├── Makefile │ ├── Socket.cpp │ ├── Socket.h │ ├── client.cpp │ ├── server.cpp │ ├── util.cpp │ └── util.h ├── day06 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ └── src │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── util.cpp │ │ └── util.h ├── day07 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ └── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── util.cpp │ │ └── util.h ├── day08 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ └── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── util.cpp │ │ └── util.h ├── day09 │ ├── Makefile │ ├── client.cpp │ ├── server.cpp │ └── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── util.cpp │ │ └── util.h ├── day10 │ ├── Makefile │ ├── ThreadPoolTest.cpp │ ├── client.cpp │ ├── server.cpp │ └── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ ├── util.cpp │ │ └── util.h ├── day11 │ ├── .vscode │ │ └── launch.json │ ├── Makefile │ ├── ThreadPoolTest.cpp │ ├── client.cpp │ ├── server.cpp │ ├── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── InetAddress.cpp │ │ ├── InetAddress.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ ├── util.cpp │ │ └── util.h │ └── test.cpp ├── day12 │ ├── .vscode │ │ └── launch.json │ ├── Makefile │ ├── ThreadPoolTest.cpp │ ├── client.cpp │ ├── server │ ├── server.cpp │ ├── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ ├── util.cpp │ │ └── util.h │ └── test.cpp ├── day13 │ ├── .vscode │ │ └── launch.json │ ├── Makefile │ ├── ThreadPoolTest.cpp │ ├── server.cpp │ ├── src │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Connection.cpp │ │ ├── Connection.h │ │ ├── Epoll.cpp │ │ ├── Epoll.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── Server.cpp │ │ ├── Server.h │ │ ├── Socket.cpp │ │ ├── Socket.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ ├── util.cpp │ │ └── util.h │ └── test.cpp ├── day14 │ ├── .vscode │ │ └── launch.json │ ├── Makefile │ ├── echo_server.cpp │ └── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ ├── TcpServer.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ └── common.h ├── day15 │ ├── Makefile │ ├── echo_server.cpp │ └── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ ├── TcpServer.h │ │ ├── ThreadPool.cpp │ │ ├── ThreadPool.h │ │ └── common.h ├── day16 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ ├── TcpServer.h │ │ ├── ThreadPool.cpp │ │ └── ThreadPool.h │ └── test │ │ └── echo_server.cpp ├── day17 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ └── test │ │ └── echo_server.cpp ├── day18 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ └── HttpRequest.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ └── test │ │ ├── echo_server.cpp │ │ └── test_httpcontext.cpp ├── day19 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ └── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ └── test_httpcontext.cpp ├── day20 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ └── test_httpcontext.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day21 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ └── test_httpcontext.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day22 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── LogStream.cpp │ │ └── LogStream.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day23 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day24 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Latch.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── AsyncLogging.cpp │ │ ├── AsyncLogging.h │ │ ├── LogFile.cpp │ │ ├── LogFile.h │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day25 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Latch.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── AsyncLogging.cpp │ │ ├── AsyncLogging.h │ │ ├── LogFile.cpp │ │ ├── LogFile.h │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day26 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Latch.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── AsyncLogging.cpp │ │ ├── AsyncLogging.h │ │ ├── LogFile.cpp │ │ ├── LogFile.h │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day27 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Latch.h │ │ └── common.h │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── AsyncLogging.cpp │ │ ├── AsyncLogging.h │ │ ├── LogFile.cpp │ │ ├── LogFile.h │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── static │ │ ├── cat.jpg │ │ ├── index.html │ │ └── mhw.html │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h ├── day28 │ ├── CMakeLists.txt │ ├── base │ │ ├── CurrentThread.cpp │ │ ├── CurrentThread.h │ │ ├── Latch.h │ │ └── common.h │ ├── files │ │ ├── a.txt │ │ ├── b.txt │ │ └── c.txt │ ├── http │ │ ├── HttpContext.cpp │ │ ├── HttpContext.h │ │ ├── HttpRequest.cpp │ │ ├── HttpRequest.h │ │ ├── HttpResponse.cpp │ │ ├── HttpResponse.h │ │ ├── HttpServer.cpp │ │ └── HttpServer.h │ ├── log │ │ ├── AsyncLogging.cpp │ │ ├── AsyncLogging.h │ │ ├── LogFile.cpp │ │ ├── LogFile.h │ │ ├── LogStream.cpp │ │ ├── LogStream.h │ │ ├── Logging.cpp │ │ └── Logging.h │ ├── static │ │ ├── cat.jpg │ │ ├── fileserver.html │ │ ├── index.html │ │ └── mhw.html │ ├── tcp │ │ ├── Acceptor.cpp │ │ ├── Acceptor.h │ │ ├── Buffer.cpp │ │ ├── Buffer.h │ │ ├── Channel.cpp │ │ ├── Channel.h │ │ ├── Epoller.cpp │ │ ├── Epoller.h │ │ ├── EventLoop.cpp │ │ ├── EventLoop.h │ │ ├── EventLoopThread.cpp │ │ ├── EventLoopThread.h │ │ ├── EventLoopThreadPool.cpp │ │ ├── EventLoopThreadPool.h │ │ ├── TcpConnection.cpp │ │ ├── TcpConnection.h │ │ ├── TcpServer.cpp │ │ └── TcpServer.h │ ├── test │ │ ├── echo_server.cpp │ │ ├── http_server.cpp │ │ ├── test_httpcontext.cpp │ │ └── test_logstream.cpp │ └── timer │ │ ├── TimeStamp.h │ │ ├── Timer.cpp │ │ ├── Timer.h │ │ ├── TimerQueue.cpp │ │ └── TimerQueue.h └── day29 │ ├── CMakeLists.txt │ ├── base │ ├── CurrentThread.cpp │ ├── CurrentThread.h │ ├── Latch.h │ └── common.h │ ├── files │ ├── a.txt │ ├── b.txt │ ├── c.txt │ └── d.txt │ ├── http │ ├── HttpContext.cpp │ ├── HttpContext.h │ ├── HttpRequest.cpp │ ├── HttpRequest.h │ ├── HttpResponse.cpp │ ├── HttpResponse.h │ ├── HttpServer.cpp │ └── HttpServer.h │ ├── log │ ├── AsyncLogging.cpp │ ├── AsyncLogging.h │ ├── LogFile.cpp │ ├── LogFile.h │ ├── LogStream.cpp │ ├── LogStream.h │ ├── Logging.cpp │ └── Logging.h │ ├── static │ ├── cat.jpg │ ├── fileserver.html │ ├── index.html │ └── mhw.html │ ├── tcp │ ├── Acceptor.cpp │ ├── Acceptor.h │ ├── Buffer.cpp │ ├── Buffer.h │ ├── Channel.cpp │ ├── Channel.h │ ├── Epoller.cpp │ ├── Epoller.h │ ├── EventLoop.cpp │ ├── EventLoop.h │ ├── EventLoopThread.cpp │ ├── EventLoopThread.h │ ├── EventLoopThreadPool.cpp │ ├── EventLoopThreadPool.h │ ├── TcpConnection.cpp │ ├── TcpConnection.h │ ├── TcpServer.cpp │ └── TcpServer.h │ ├── test │ ├── echo_server.cpp │ ├── http_server.cpp │ ├── test_httpcontext.cpp │ └── test_logstream.cpp │ └── timer │ ├── TimeStamp.h │ ├── Timer.cpp │ ├── Timer.h │ ├── TimerQueue.cpp │ └── TimerQueue.h ├── day01-从一个最简单的socket开始.md ├── day02-不要放过任何一个错误.md ├── day03-高并发还得用epoll.md ├── day04-来看看我们的第一个类.md ├── day05-epoll高级用法-Channel登场.md ├── day06-服务器与事件驱动核心类登场.md ├── day07-为我们的服务器添加一个Acceptor.md ├── day08-一切皆是类,连TCP连接也不例外.md ├── day09-缓冲区-大作用.md ├── day10-加入线程池到服务器.md ├── day11-完善线程池,加入一个简单的测试程序.md ├── day12-将服务器改写为主从Reactor多线程模式.md ├── day13-支持业务逻辑自定义、完善Connection类.md ├── day14-重构核心库、使用智能指针.md ├── day15-重构Connection、修改生命周期.md ├── day16-使用CMake工程化.md ├── day17-使用EventLoopThreadPool、移交EventLoop.md ├── day18-HTTP有限状态转换机.md ├── day19-创建HTTP响应,实现HTTP服务器.md ├── day20-定时器的创建使用.md ├── day21-服务器主动关闭连接.md ├── day22-初步涉及日志库,定义自己的输出流LogStream.md ├── day23-定义前端日志库,实现同步输出.md ├── day24-异步日志库.md ├── day25-更有效的缓冲区.md ├── day26-监听写事件.md ├── day27-处理静态文件,实现POST请求.md ├── day28-文件服务器的简单实现,文件的展示和下载.md ├── day29-文件的上传.md └── day30-WebBench的测试.md /code/day01/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ server.cpp -o server && g++ client.cpp -o client -------------------------------------------------------------------------------- /code/day01/client.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2022-01-04 20:03:45 4 | * @LastEditTime: 2022-01-05 19:08:58 5 | * @LastEditors: your name 6 | * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE 7 | * @FilePath: \30dayMakeCppServer\code\day01\client.cpp 8 | */ 9 | #include 10 | #include 11 | #include 12 | 13 | int main() { 14 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 15 | 16 | struct sockaddr_in serv_addr; 17 | bzero(&serv_addr, sizeof(serv_addr)); 18 | serv_addr.sin_family = AF_INET; 19 | serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 20 | serv_addr.sin_port = htons(8888); 21 | 22 | //bind(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr)); 客户端不进行bind操作 23 | 24 | connect(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /code/day01/server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() { 7 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 8 | 9 | struct sockaddr_in serv_addr; 10 | bzero(&serv_addr, sizeof(serv_addr)); 11 | serv_addr.sin_family = AF_INET; 12 | serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 13 | serv_addr.sin_port = htons(8888); 14 | 15 | bind(sockfd, (sockaddr*)&serv_addr, sizeof(serv_addr)); 16 | 17 | listen(sockfd, SOMAXCONN); 18 | 19 | struct sockaddr_in clnt_addr; 20 | socklen_t clnt_addr_len = sizeof(clnt_addr); 21 | bzero(&clnt_addr, sizeof(clnt_addr)); 22 | 23 | int clnt_sockfd = accept(sockfd, (sockaddr*)&clnt_addr, &clnt_addr_len); 24 | 25 | printf("new client fd %d! IP: %s Port: %d\n", clnt_sockfd, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port)); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /code/day02/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ util.cpp client.cpp -o client && \ 3 | g++ util.cpp server.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day02/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day02/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day03/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ util.cpp client.cpp -o client && \ 3 | g++ util.cpp server.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day03/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day03/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day04/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Epoll 6 | { 7 | private: 8 | int epfd; 9 | struct epoll_event *events; 10 | public: 11 | Epoll(); 12 | ~Epoll(); 13 | 14 | void addFd(int fd, uint32_t op); 15 | std::vector poll(int timeout = -1); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day04/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | -------------------------------------------------------------------------------- /code/day04/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | public: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | InetAddress(); 10 | InetAddress(const char* ip, uint16_t port); 11 | ~InetAddress(); 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /code/day04/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ util.cpp client.cpp -o client && \ 3 | g++ util.cpp server.cpp Epoll.cpp InetAddress.cpp Socket.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day04/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | 19 | int getFd(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day04/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day04/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day05/Channel.cpp: -------------------------------------------------------------------------------- 1 | #include "Channel.h" 2 | #include "Epoll.h" 3 | 4 | Channel::Channel(Epoll *_ep, int _fd) : ep(_ep), fd(_fd), events(0), revents(0), inEpoll(false){ 5 | 6 | } 7 | 8 | Channel::~Channel() 9 | { 10 | } 11 | 12 | void Channel::enableReading(){ 13 | events = EPOLLIN | EPOLLET; 14 | ep->updateChannel(this); 15 | } 16 | 17 | int Channel::getFd(){ 18 | return fd; 19 | } 20 | 21 | uint32_t Channel::getEvents(){ 22 | return events; 23 | } 24 | uint32_t Channel::getRevents(){ 25 | return revents; 26 | } 27 | 28 | bool Channel::getInEpoll(){ 29 | return inEpoll; 30 | } 31 | 32 | void Channel::setInEpoll(){ 33 | inEpoll = true; 34 | } 35 | 36 | // void Channel::setEvents(uint32_t _ev){ 37 | // events = _ev; 38 | // } 39 | 40 | void Channel::setRevents(uint32_t _ev){ 41 | revents = _ev; 42 | } -------------------------------------------------------------------------------- /code/day05/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Epoll; 5 | class Channel 6 | { 7 | private: 8 | Epoll *ep; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | public: 14 | Channel(Epoll *_ep, int _fd); 15 | ~Channel(); 16 | 17 | void enableReading(); 18 | 19 | int getFd(); 20 | uint32_t getEvents(); 21 | uint32_t getRevents(); 22 | bool getInEpoll(); 23 | void setInEpoll(); 24 | 25 | // void setEvents(uint32_t); 26 | void setRevents(uint32_t); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /code/day05/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day05/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | -------------------------------------------------------------------------------- /code/day05/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | public: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | InetAddress(); 10 | InetAddress(const char* ip, uint16_t port); 11 | ~InetAddress(); 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /code/day05/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ util.cpp client.cpp -o client && \ 3 | g++ util.cpp server.cpp Epoll.cpp InetAddress.cpp Socket.cpp Channel.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day05/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | 19 | int getFd(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day05/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day05/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day06/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ src/util.cpp client.cpp -o client && \ 3 | g++ src/util.cpp server.cpp src/Epoll.cpp src/InetAddress.cpp src/Socket.cpp src/Channel.cpp src/EventLoop.cpp src/Server.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day06/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /code/day06/src/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Channel 6 | { 7 | private: 8 | EventLoop *loop; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | std::function callback; 14 | public: 15 | Channel(EventLoop *_loop, int _fd); 16 | ~Channel(); 17 | 18 | void handleEvent(); 19 | void enableReading(); 20 | 21 | int getFd(); 22 | uint32_t getEvents(); 23 | uint32_t getRevents(); 24 | bool getInEpoll(); 25 | void setInEpoll(); 26 | 27 | // void setEvents(uint32_t); 28 | void setRevents(uint32_t); 29 | void setCallback(std::function); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day06/src/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day06/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Epoll.h" 3 | #include "Channel.h" 4 | #include 5 | 6 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 7 | ep = new Epoll(); 8 | } 9 | 10 | EventLoop::~EventLoop() 11 | { 12 | delete ep; 13 | } 14 | 15 | 16 | void EventLoop::loop(){ 17 | while(!quit){ 18 | std::vector chs; 19 | chs = ep->poll(); 20 | for(auto it = chs.begin(); it != chs.end(); ++it){ 21 | (*it)->handleEvent(); 22 | } 23 | } 24 | } 25 | 26 | void EventLoop::updateChannel(Channel *ch){ 27 | ep->updateChannel(ch); 28 | } -------------------------------------------------------------------------------- /code/day06/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class Epoll; 3 | class Channel; 4 | class EventLoop 5 | { 6 | private: 7 | Epoll *ep; 8 | bool quit; 9 | public: 10 | EventLoop(); 11 | ~EventLoop(); 12 | 13 | void loop(); 14 | void updateChannel(Channel*); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /code/day06/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | -------------------------------------------------------------------------------- /code/day06/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | public: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | InetAddress(); 10 | InetAddress(const char* ip, uint16_t port); 11 | ~InetAddress(); 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /code/day06/src/Server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class EventLoop; 4 | class Socket; 5 | class Server 6 | { 7 | private: 8 | EventLoop *loop; 9 | public: 10 | Server(EventLoop*); 11 | ~Server(); 12 | 13 | void handleReadEvent(int); 14 | void newConnection(Socket *serv_sock); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /code/day06/src/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | 19 | int getFd(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day06/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day06/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day07/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ src/util.cpp client.cpp -o client && \ 3 | g++ src/util.cpp server.cpp src/Epoll.cpp src/InetAddress.cpp src/Socket.cpp src/Channel.cpp src/EventLoop.cpp src/Server.cpp src/Acceptor.cpp -o server 4 | clean: 5 | rm server && rm client -------------------------------------------------------------------------------- /code/day07/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | return 0; 9 | } -------------------------------------------------------------------------------- /code/day07/src/Acceptor.cpp: -------------------------------------------------------------------------------- 1 | #include "Acceptor.h" 2 | #include "Socket.h" 3 | #include "InetAddress.h" 4 | #include "Channel.h" 5 | #include "Server.h" 6 | 7 | Acceptor::Acceptor(EventLoop *_loop) : loop(_loop) 8 | { 9 | sock = new Socket(); 10 | addr = new InetAddress("127.0.0.1", 8888); 11 | sock->bind(addr); 12 | sock->listen(); 13 | sock->setnonblocking(); 14 | acceptChannel = new Channel(loop, sock->getFd()); 15 | std::function cb = std::bind(&Acceptor::acceptConnection, this); 16 | acceptChannel->setCallback(cb); 17 | acceptChannel->enableReading(); 18 | } 19 | 20 | Acceptor::~Acceptor(){ 21 | delete sock; 22 | delete addr; 23 | delete acceptChannel; 24 | } 25 | 26 | void Acceptor::acceptConnection(){ 27 | newConnectionCallback(sock); 28 | } 29 | 30 | void Acceptor::setNewConnectionCallback(std::function _cb){ 31 | newConnectionCallback = _cb; 32 | } -------------------------------------------------------------------------------- /code/day07/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class EventLoop; 5 | class Socket; 6 | class InetAddress; 7 | class Channel; 8 | class Acceptor 9 | { 10 | private: 11 | EventLoop *loop; 12 | Socket *sock; 13 | InetAddress *addr; 14 | Channel *acceptChannel; 15 | public: 16 | Acceptor(EventLoop *_loop); 17 | ~Acceptor(); 18 | void acceptConnection(); 19 | std::function newConnectionCallback; 20 | void setNewConnectionCallback(std::function); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /code/day07/src/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Channel 6 | { 7 | private: 8 | EventLoop *loop; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | std::function callback; 14 | public: 15 | Channel(EventLoop *_loop, int _fd); 16 | ~Channel(); 17 | 18 | void handleEvent(); 19 | void enableReading(); 20 | 21 | int getFd(); 22 | uint32_t getEvents(); 23 | uint32_t getRevents(); 24 | bool getInEpoll(); 25 | void setInEpoll(); 26 | 27 | // void setEvents(uint32_t); 28 | void setRevents(uint32_t); 29 | void setCallback(std::function); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day07/src/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day07/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Epoll.h" 3 | #include "Channel.h" 4 | #include 5 | 6 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 7 | ep = new Epoll(); 8 | } 9 | 10 | EventLoop::~EventLoop() 11 | { 12 | delete ep; 13 | } 14 | 15 | 16 | void EventLoop::loop(){ 17 | while(!quit){ 18 | std::vector chs; 19 | chs = ep->poll(); 20 | for(auto it = chs.begin(); it != chs.end(); ++it){ 21 | (*it)->handleEvent(); 22 | } 23 | } 24 | } 25 | 26 | void EventLoop::updateChannel(Channel *ch){ 27 | ep->updateChannel(ch); 28 | } -------------------------------------------------------------------------------- /code/day07/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class Epoll; 3 | class Channel; 4 | class EventLoop 5 | { 6 | private: 7 | Epoll *ep; 8 | bool quit; 9 | public: 10 | EventLoop(); 11 | ~EventLoop(); 12 | 13 | void loop(); 14 | void updateChannel(Channel*); 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /code/day07/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | -------------------------------------------------------------------------------- /code/day07/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | public: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | InetAddress(); 10 | InetAddress(const char* ip, uint16_t port); 11 | ~InetAddress(); 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /code/day07/src/Server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class EventLoop; 4 | class Socket; 5 | class Acceptor; 6 | class Server 7 | { 8 | private: 9 | EventLoop *loop; 10 | Acceptor *acceptor; 11 | public: 12 | Server(EventLoop*); 13 | ~Server(); 14 | 15 | void handleReadEvent(int); 16 | void newConnection(Socket *serv_sock); 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /code/day07/src/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | 19 | int getFd(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day07/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day07/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day08/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ src/util.cpp client.cpp -o client && \ 3 | g++ server.cpp \ 4 | src/util.cpp src/Epoll.cpp src/InetAddress.cpp src/Socket.cpp src/Connection.cpp \ 5 | src/Channel.cpp src/EventLoop.cpp src/Server.cpp src/Acceptor.cpp \ 6 | -o server 7 | clean: 8 | rm server && rm client -------------------------------------------------------------------------------- /code/day08/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /code/day08/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Acceptor 8 | { 9 | private: 10 | EventLoop *loop; 11 | Socket *sock; 12 | Channel *acceptChannel; 13 | std::function newConnectionCallback; 14 | public: 15 | Acceptor(EventLoop *_loop); 16 | ~Acceptor(); 17 | void acceptConnection(); 18 | void setNewConnectionCallback(std::function); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day08/src/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Channel 6 | { 7 | private: 8 | EventLoop *loop; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | std::function callback; 14 | public: 15 | Channel(EventLoop *_loop, int _fd); 16 | ~Channel(); 17 | 18 | void handleEvent(); 19 | void enableReading(); 20 | 21 | int getFd(); 22 | uint32_t getEvents(); 23 | uint32_t getRevents(); 24 | bool getInEpoll(); 25 | void setInEpoll(); 26 | 27 | // void setEvents(uint32_t); 28 | void setRevents(uint32_t); 29 | void setCallback(std::function); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day08/src/Connection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Connection 8 | { 9 | private: 10 | EventLoop *loop; 11 | Socket *sock; 12 | Channel *channel; 13 | std::function deleteConnectionCallback; 14 | public: 15 | Connection(EventLoop *_loop, Socket *_sock); 16 | ~Connection(); 17 | 18 | void echo(int sockfd); 19 | void setDeleteConnectionCallback(std::function); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day08/src/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | // void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day08/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Epoll.h" 3 | #include "Channel.h" 4 | #include 5 | 6 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 7 | ep = new Epoll(); 8 | } 9 | 10 | EventLoop::~EventLoop() 11 | { 12 | delete ep; 13 | } 14 | 15 | 16 | void EventLoop::loop(){ 17 | while(!quit){ 18 | std::vector chs; 19 | chs = ep->poll(); 20 | for(auto it = chs.begin(); it != chs.end(); ++it){ 21 | (*it)->handleEvent(); 22 | } 23 | } 24 | } 25 | 26 | void EventLoop::updateChannel(Channel *ch){ 27 | ep->updateChannel(ch); 28 | } -------------------------------------------------------------------------------- /code/day08/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Epoll; 4 | class Channel; 5 | class EventLoop 6 | { 7 | private: 8 | Epoll *ep; 9 | bool quit; 10 | public: 11 | EventLoop(); 12 | ~EventLoop(); 13 | 14 | void loop(); 15 | void updateChannel(Channel*); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day08/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | 17 | void InetAddress::setInetAddr(sockaddr_in _addr, socklen_t _addr_len){ 18 | addr = _addr; 19 | addr_len = _addr_len; 20 | } 21 | 22 | sockaddr_in InetAddress::getAddr(){ 23 | return addr; 24 | } 25 | socklen_t InetAddress::getAddr_len(){ 26 | return addr_len; 27 | } -------------------------------------------------------------------------------- /code/day08/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | private: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | public: 10 | InetAddress(); 11 | InetAddress(const char* ip, uint16_t port); 12 | ~InetAddress(); 13 | void setInetAddr(sockaddr_in _addr, socklen_t _addr_len); 14 | sockaddr_in getAddr(); 15 | socklen_t getAddr_len(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day08/src/Server.cpp: -------------------------------------------------------------------------------- 1 | #include "Server.h" 2 | #include "Socket.h" 3 | #include "Acceptor.h" 4 | #include "Connection.h" 5 | #include 6 | 7 | 8 | Server::Server(EventLoop *_loop) : loop(_loop), acceptor(nullptr){ 9 | acceptor = new Acceptor(loop); 10 | std::function cb = std::bind(&Server::newConnection, this, std::placeholders::_1); 11 | acceptor->setNewConnectionCallback(cb); 12 | } 13 | 14 | Server::~Server(){ 15 | delete acceptor; 16 | } 17 | 18 | 19 | void Server::newConnection(Socket *sock){ 20 | Connection *conn = new Connection(loop, sock); 21 | std::function cb = std::bind(&Server::deleteConnection, this, std::placeholders::_1); 22 | conn->setDeleteConnectionCallback(cb); 23 | connections[sock->getFd()] = conn; 24 | } 25 | 26 | void Server::deleteConnection(Socket * sock){ 27 | Connection *conn = connections[sock->getFd()]; 28 | connections.erase(sock->getFd()); 29 | delete conn; 30 | } -------------------------------------------------------------------------------- /code/day08/src/Server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Acceptor; 7 | class Connection; 8 | class Server 9 | { 10 | private: 11 | EventLoop *loop; 12 | Acceptor *acceptor; 13 | std::map connections; 14 | public: 15 | Server(EventLoop*); 16 | ~Server(); 17 | 18 | void handleReadEvent(int); 19 | void newConnection(Socket *sock); 20 | void deleteConnection(Socket *sock); 21 | }; 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day08/src/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int _fd); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | 19 | int getFd(); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /code/day08/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day08/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day09/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp client.cpp -o client && \ 3 | g++ server.cpp \ 4 | src/util.cpp src/Epoll.cpp src/InetAddress.cpp src/Socket.cpp src/Connection.cpp \ 5 | src/Channel.cpp src/EventLoop.cpp src/Server.cpp src/Acceptor.cpp src/Buffer.cpp \ 6 | -o server 7 | clean: 8 | rm server && rm client -------------------------------------------------------------------------------- /code/day09/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | delete server; 9 | delete loop; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /code/day09/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Acceptor 8 | { 9 | private: 10 | EventLoop *loop; 11 | Socket *sock; 12 | Channel *acceptChannel; 13 | std::function newConnectionCallback; 14 | public: 15 | Acceptor(EventLoop *_loop); 16 | ~Acceptor(); 17 | void acceptConnection(); 18 | void setNewConnectionCallback(std::function); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day09/src/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | #include 3 | #include 4 | Buffer::Buffer() 5 | { 6 | } 7 | 8 | Buffer::~Buffer() 9 | { 10 | } 11 | 12 | 13 | void Buffer::append(const char* _str, int _size){ 14 | for(int i = 0; i < _size; ++i){ 15 | if(_str[i] == '\0') break; 16 | buf.push_back(_str[i]); 17 | } 18 | } 19 | 20 | ssize_t Buffer::size(){ 21 | return buf.size(); 22 | } 23 | 24 | const char* Buffer::c_str(){ 25 | return buf.c_str(); 26 | } 27 | 28 | void Buffer::clear(){ 29 | buf.clear(); 30 | } 31 | 32 | void Buffer::getline(){ 33 | buf.clear(); 34 | std::getline(std::cin, buf); 35 | } -------------------------------------------------------------------------------- /code/day09/src/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Buffer 5 | { 6 | private: 7 | std::string buf; 8 | public: 9 | Buffer(); 10 | ~Buffer(); 11 | void append(const char* _str, int _size); 12 | ssize_t size(); 13 | const char* c_str(); 14 | void clear(); 15 | void getline(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day09/src/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Channel 6 | { 7 | private: 8 | EventLoop *loop; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | std::function callback; 14 | public: 15 | Channel(EventLoop *_loop, int _fd); 16 | ~Channel(); 17 | 18 | void handleEvent(); 19 | void enableReading(); 20 | 21 | int getFd(); 22 | uint32_t getEvents(); 23 | uint32_t getRevents(); 24 | bool getInEpoll(); 25 | void setInEpoll(); 26 | 27 | // void setEvents(uint32_t); 28 | void setRevents(uint32_t); 29 | void setCallback(std::function); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day09/src/Connection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Buffer; 8 | class Connection 9 | { 10 | private: 11 | EventLoop *loop; 12 | Socket *sock; 13 | Channel *channel; 14 | std::function deleteConnectionCallback; 15 | std::string *inBuffer; 16 | Buffer *readBuffer; 17 | public: 18 | Connection(EventLoop *_loop, Socket *_sock); 19 | ~Connection(); 20 | 21 | void echo(int sockfd); 22 | void setDeleteConnectionCallback(std::function); 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /code/day09/src/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | // void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day09/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Epoll.h" 3 | #include "Channel.h" 4 | #include 5 | 6 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 7 | ep = new Epoll(); 8 | } 9 | 10 | EventLoop::~EventLoop(){ 11 | delete ep; 12 | } 13 | 14 | 15 | void EventLoop::loop(){ 16 | while(!quit){ 17 | std::vector chs; 18 | chs = ep->poll(); 19 | for(auto it = chs.begin(); it != chs.end(); ++it){ 20 | (*it)->handleEvent(); 21 | } 22 | } 23 | } 24 | 25 | void EventLoop::updateChannel(Channel *ch){ 26 | ep->updateChannel(ch); 27 | } -------------------------------------------------------------------------------- /code/day09/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class Epoll; 4 | class Channel; 5 | class EventLoop 6 | { 7 | private: 8 | Epoll *ep; 9 | bool quit; 10 | public: 11 | EventLoop(); 12 | ~EventLoop(); 13 | 14 | void loop(); 15 | void updateChannel(Channel*); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day09/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | 17 | void InetAddress::setInetAddr(sockaddr_in _addr, socklen_t _addr_len){ 18 | addr = _addr; 19 | addr_len = _addr_len; 20 | } 21 | 22 | sockaddr_in InetAddress::getAddr(){ 23 | return addr; 24 | } 25 | socklen_t InetAddress::getAddr_len(){ 26 | return addr_len; 27 | } -------------------------------------------------------------------------------- /code/day09/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | private: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | public: 10 | InetAddress(); 11 | InetAddress(const char* ip, uint16_t port); 12 | ~InetAddress(); 13 | void setInetAddr(sockaddr_in _addr, socklen_t _addr_len); 14 | sockaddr_in getAddr(); 15 | socklen_t getAddr_len(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day09/src/Server.cpp: -------------------------------------------------------------------------------- 1 | #include "Server.h" 2 | #include "Socket.h" 3 | #include "Acceptor.h" 4 | #include "Connection.h" 5 | #include 6 | 7 | 8 | Server::Server(EventLoop *_loop) : loop(_loop), acceptor(nullptr){ 9 | acceptor = new Acceptor(loop); 10 | std::function cb = std::bind(&Server::newConnection, this, std::placeholders::_1); 11 | acceptor->setNewConnectionCallback(cb); 12 | } 13 | 14 | Server::~Server(){ 15 | delete acceptor; 16 | } 17 | 18 | 19 | void Server::newConnection(Socket *sock){ 20 | Connection *conn = new Connection(loop, sock); 21 | std::function cb = std::bind(&Server::deleteConnection, this, std::placeholders::_1); 22 | conn->setDeleteConnectionCallback(cb); 23 | connections[sock->getFd()] = conn; 24 | } 25 | 26 | void Server::deleteConnection(Socket *sock){ 27 | Connection *conn = connections[sock->getFd()]; 28 | connections.erase(sock->getFd()); 29 | delete conn; 30 | } -------------------------------------------------------------------------------- /code/day09/src/Server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Acceptor; 7 | class Connection; 8 | class Server 9 | { 10 | private: 11 | EventLoop *loop; 12 | Acceptor *acceptor; 13 | std::map connections; 14 | public: 15 | Server(EventLoop*); 16 | ~Server(); 17 | 18 | void handleReadEvent(int); 19 | void newConnection(Socket *sock); 20 | void deleteConnection(Socket *sock); 21 | }; 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day09/src/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int _fd); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | void connect(InetAddress*); 19 | 20 | int getFd(); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /code/day09/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day09/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day10/Makefile: -------------------------------------------------------------------------------- 1 | server: 2 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp client.cpp -o client && \ 3 | g++ server.cpp \ 4 | -pthread \ 5 | src/util.cpp src/Epoll.cpp src/InetAddress.cpp src/Socket.cpp src/Connection.cpp \ 6 | src/Channel.cpp src/EventLoop.cpp src/Server.cpp src/Acceptor.cpp src/Buffer.cpp \ 7 | src/ThreadPool.cpp \ 8 | -o server 9 | clean: 10 | rm server && rm client 11 | 12 | threadTest: 13 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest -------------------------------------------------------------------------------- /code/day10/ThreadPoolTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/ThreadPool.h" 4 | 5 | void print(int a, double b, const char *c, std::string d){ 6 | std::cout << a << b << c << d << std::endl; 7 | } 8 | 9 | void test(){ 10 | std::cout << "hellp" << std::endl; 11 | } 12 | 13 | int main(int argc, char const *argv[]) 14 | { 15 | ThreadPool *poll = new ThreadPool(); 16 | std::function func = std::bind(print, 1, 3.14, "hello", std::string("world")); 17 | poll->add(func); 18 | func = test; 19 | poll->add(func); 20 | delete poll; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /code/day10/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | delete server; 9 | delete loop; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /code/day10/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Acceptor 8 | { 9 | private: 10 | EventLoop *loop; 11 | Socket *sock; 12 | Channel *acceptChannel; 13 | std::function newConnectionCallback; 14 | public: 15 | Acceptor(EventLoop *_loop); 16 | ~Acceptor(); 17 | void acceptConnection(); 18 | void setNewConnectionCallback(std::function); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day10/src/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | #include 3 | #include 4 | Buffer::Buffer() 5 | { 6 | } 7 | 8 | Buffer::~Buffer() 9 | { 10 | } 11 | 12 | 13 | void Buffer::append(const char* _str, int _size){ 14 | for(int i = 0; i < _size; ++i){ 15 | if(_str[i] == '\0') break; 16 | buf.push_back(_str[i]); 17 | } 18 | } 19 | 20 | ssize_t Buffer::size(){ 21 | return buf.size(); 22 | } 23 | 24 | const char* Buffer::c_str(){ 25 | return buf.c_str(); 26 | } 27 | 28 | void Buffer::clear(){ 29 | buf.clear(); 30 | } 31 | 32 | void Buffer::getline(){ 33 | buf.clear(); 34 | std::getline(std::cin, buf); 35 | } -------------------------------------------------------------------------------- /code/day10/src/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Buffer 5 | { 6 | private: 7 | std::string buf; 8 | public: 9 | Buffer(); 10 | ~Buffer(); 11 | void append(const char* _str, int _size); 12 | ssize_t size(); 13 | const char* c_str(); 14 | void clear(); 15 | void getline(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day10/src/Channel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Channel 6 | { 7 | private: 8 | EventLoop *loop; 9 | int fd; 10 | uint32_t events; 11 | uint32_t revents; 12 | bool inEpoll; 13 | std::function callback; 14 | public: 15 | Channel(EventLoop *_loop, int _fd); 16 | ~Channel(); 17 | 18 | void handleEvent(); 19 | void enableReading(); 20 | 21 | int getFd(); 22 | uint32_t getEvents(); 23 | uint32_t getRevents(); 24 | bool getInEpoll(); 25 | void setInEpoll(); 26 | 27 | // void setEvents(uint32_t); 28 | void setRevents(uint32_t); 29 | void setCallback(std::function); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day10/src/Connection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Channel; 7 | class Buffer; 8 | class Connection 9 | { 10 | private: 11 | EventLoop *loop; 12 | Socket *sock; 13 | Channel *channel; 14 | std::function deleteConnectionCallback; 15 | std::string *inBuffer; 16 | Buffer *readBuffer; 17 | public: 18 | Connection(EventLoop *_loop, Socket *_sock); 19 | ~Connection(); 20 | 21 | void echo(int sockfd); 22 | void setDeleteConnectionCallback(std::function); 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /code/day10/src/Epoll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Channel; 6 | class Epoll 7 | { 8 | private: 9 | int epfd; 10 | struct epoll_event *events; 11 | public: 12 | Epoll(); 13 | ~Epoll(); 14 | 15 | // void addFd(int fd, uint32_t op); 16 | void updateChannel(Channel*); 17 | // std::vector poll(int timeout = -1); 18 | std::vector poll(int timeout = -1); 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /code/day10/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include "Epoll.h" 3 | #include "Channel.h" 4 | #include "ThreadPool.h" 5 | #include 6 | 7 | EventLoop::EventLoop() : ep(nullptr), threadPool(nullptr), quit(false){ 8 | ep = new Epoll(); 9 | threadPool = new ThreadPool(); 10 | } 11 | 12 | EventLoop::~EventLoop(){ 13 | delete ep; 14 | } 15 | 16 | 17 | void EventLoop::loop(){ 18 | while(!quit){ 19 | std::vector chs; 20 | chs = ep->poll(); 21 | for(auto it = chs.begin(); it != chs.end(); ++it){ 22 | (*it)->handleEvent(); 23 | } 24 | } 25 | } 26 | 27 | void EventLoop::updateChannel(Channel *ch){ 28 | ep->updateChannel(ch); 29 | } 30 | 31 | void EventLoop::addThread(std::function func){ 32 | threadPool->add(func); 33 | } -------------------------------------------------------------------------------- /code/day10/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Epoll; 5 | class Channel; 6 | class ThreadPool; 7 | class EventLoop 8 | { 9 | private: 10 | Epoll *ep; 11 | ThreadPool *threadPool; 12 | bool quit; 13 | public: 14 | EventLoop(); 15 | ~EventLoop(); 16 | 17 | void loop(); 18 | void updateChannel(Channel*); 19 | 20 | void addThread(std::function); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /code/day10/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | #include "InetAddress.h" 2 | #include 3 | InetAddress::InetAddress() : addr_len(sizeof(addr)){ 4 | bzero(&addr, sizeof(addr)); 5 | } 6 | InetAddress::InetAddress(const char* ip, uint16_t port) : addr_len(sizeof(addr)){ 7 | bzero(&addr, sizeof(addr)); 8 | addr.sin_family = AF_INET; 9 | addr.sin_addr.s_addr = inet_addr(ip); 10 | addr.sin_port = htons(port); 11 | addr_len = sizeof(addr); 12 | } 13 | 14 | InetAddress::~InetAddress(){ 15 | } 16 | 17 | void InetAddress::setInetAddr(sockaddr_in _addr, socklen_t _addr_len){ 18 | addr = _addr; 19 | addr_len = _addr_len; 20 | } 21 | 22 | sockaddr_in InetAddress::getAddr(){ 23 | return addr; 24 | } 25 | socklen_t InetAddress::getAddr_len(){ 26 | return addr_len; 27 | } -------------------------------------------------------------------------------- /code/day10/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class InetAddress 5 | { 6 | private: 7 | struct sockaddr_in addr; 8 | socklen_t addr_len; 9 | public: 10 | InetAddress(); 11 | InetAddress(const char* ip, uint16_t port); 12 | ~InetAddress(); 13 | void setInetAddr(sockaddr_in _addr, socklen_t _addr_len); 14 | sockaddr_in getAddr(); 15 | socklen_t getAddr_len(); 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /code/day10/src/Server.cpp: -------------------------------------------------------------------------------- 1 | #include "Server.h" 2 | #include "Socket.h" 3 | #include "Acceptor.h" 4 | #include "Connection.h" 5 | #include 6 | 7 | 8 | Server::Server(EventLoop *_loop) : loop(_loop), acceptor(nullptr){ 9 | acceptor = new Acceptor(loop); 10 | std::function cb = std::bind(&Server::newConnection, this, std::placeholders::_1); 11 | acceptor->setNewConnectionCallback(cb); 12 | } 13 | 14 | Server::~Server(){ 15 | delete acceptor; 16 | } 17 | 18 | 19 | void Server::newConnection(Socket *sock){ 20 | Connection *conn = new Connection(loop, sock); 21 | std::function cb = std::bind(&Server::deleteConnection, this, std::placeholders::_1); 22 | conn->setDeleteConnectionCallback(cb); 23 | connections[sock->getFd()] = conn; 24 | } 25 | 26 | void Server::deleteConnection(Socket *sock){ 27 | Connection *conn = connections[sock->getFd()]; 28 | connections.erase(sock->getFd()); 29 | delete conn; 30 | } -------------------------------------------------------------------------------- /code/day10/src/Server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | class EventLoop; 5 | class Socket; 6 | class Acceptor; 7 | class Connection; 8 | class Server 9 | { 10 | private: 11 | EventLoop *loop; 12 | Acceptor *acceptor; 13 | std::map connections; 14 | public: 15 | Server(EventLoop*); 16 | ~Server(); 17 | 18 | void handleReadEvent(int); 19 | void newConnection(Socket *sock); 20 | void deleteConnection(Socket *sock); 21 | }; 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day10/src/Socket.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class InetAddress; 4 | class Socket 5 | { 6 | private: 7 | int fd; 8 | public: 9 | Socket(); 10 | Socket(int _fd); 11 | ~Socket(); 12 | 13 | void bind(InetAddress*); 14 | void listen(); 15 | void setnonblocking(); 16 | 17 | int accept(InetAddress*); 18 | void connect(InetAddress*); 19 | 20 | int getFd(); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /code/day10/src/ThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class ThreadPool 10 | { 11 | private: 12 | std::vector threads; 13 | std::queue> tasks; 14 | std::mutex tasks_mtx; 15 | std::condition_variable cv; 16 | bool stop; 17 | public: 18 | ThreadPool(int size = 10); 19 | ~ThreadPool(); 20 | 21 | void add(std::function); 22 | 23 | }; 24 | -------------------------------------------------------------------------------- /code/day10/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day10/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day11/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) Launch", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/server", 12 | "args": [], 13 | "stopAtEntry": false, 14 | "cwd": "${fileDirname}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "setupCommands": [ 19 | { 20 | "description": "Enable pretty-printing for gdb", 21 | "text": "-enable-pretty-printing", 22 | "ignoreFailures": true 23 | } 24 | ] 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /code/day11/Makefile: -------------------------------------------------------------------------------- 1 | src=$(wildcard src/*.cpp) 2 | 3 | server: 4 | g++ -std=c++11 -pthread -g \ 5 | $(src) \ 6 | server.cpp \ 7 | -o server 8 | 9 | client: 10 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp client.cpp -o client 11 | 12 | th: 13 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest 14 | 15 | test: 16 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp src/ThreadPool.cpp \ 17 | -pthread \ 18 | test.cpp -o test 19 | 20 | clean: 21 | rm server && rm client && rm test -------------------------------------------------------------------------------- /code/day11/ThreadPoolTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/ThreadPool.h" 4 | 5 | void print(int a, double b, const char *c, std::string d){ 6 | std::cout << a << b << c << d << std::endl; 7 | } 8 | 9 | void test(){ 10 | std::cout << "hellp" << std::endl; 11 | } 12 | 13 | int main(int argc, char const *argv[]) 14 | { 15 | ThreadPool *poll = new ThreadPool(); 16 | std::function func = std::bind(print, 1, 3.14, "hello", std::string("world")); 17 | poll->add(func); 18 | func = test; 19 | poll->add(func); 20 | delete poll; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /code/day11/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /code/day11/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class EventLoop; 11 | class Socket; 12 | class Channel; 13 | class Acceptor 14 | { 15 | private: 16 | EventLoop *loop; 17 | Socket *sock; 18 | Channel *acceptChannel; 19 | std::function newConnectionCallback; 20 | public: 21 | Acceptor(EventLoop *_loop); 22 | ~Acceptor(); 23 | void acceptConnection(); 24 | void setNewConnectionCallback(std::function); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day11/src/Buffer.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "Buffer.h" 8 | #include 9 | #include 10 | Buffer::Buffer() {} 11 | 12 | Buffer::~Buffer() {} 13 | 14 | void Buffer::append(const char* _str, int _size){ 15 | for(int i = 0; i < _size; ++i){ 16 | if(_str[i] == '\0') break; 17 | buf.push_back(_str[i]); 18 | } 19 | } 20 | 21 | ssize_t Buffer::size(){ 22 | return buf.size(); 23 | } 24 | 25 | const char* Buffer::c_str(){ 26 | return buf.c_str(); 27 | } 28 | 29 | void Buffer::clear(){ 30 | buf.clear(); 31 | } 32 | 33 | void Buffer::getline(){ 34 | buf.clear(); 35 | std::getline(std::cin, buf); 36 | } 37 | 38 | void Buffer::setBuf(const char* _buf){ 39 | buf.clear(); 40 | buf.append(_buf); 41 | } -------------------------------------------------------------------------------- /code/day11/src/Buffer.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class Buffer 11 | { 12 | private: 13 | std::string buf; 14 | public: 15 | Buffer(); 16 | ~Buffer(); 17 | 18 | void append(const char* _str, int _size); 19 | ssize_t size(); 20 | const char* c_str(); 21 | void clear(); 22 | void getline(); 23 | void setBuf(const char*); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /code/day11/src/Channel.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | class Socket; 10 | class EventLoop; 11 | class Channel 12 | { 13 | private: 14 | EventLoop *loop; 15 | int fd; 16 | uint32_t events; 17 | uint32_t ready; 18 | bool inEpoll; 19 | bool useThreadPool; 20 | std::function readCallback; 21 | std::function writeCallback; 22 | public: 23 | Channel(EventLoop *_loop, int _fd); 24 | ~Channel(); 25 | 26 | void handleEvent(); 27 | void enableRead(); 28 | 29 | int getFd(); 30 | uint32_t getEvents(); 31 | uint32_t getReady(); 32 | bool getInEpoll(); 33 | void setInEpoll(bool _in = true); 34 | void useET(); 35 | 36 | void setReady(uint32_t); 37 | void setReadCallback(std::function); 38 | void setUseThreadPool(bool use = true); 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /code/day11/src/Connection.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | class EventLoop; 11 | class Socket; 12 | class Channel; 13 | class Buffer; 14 | class Connection 15 | { 16 | private: 17 | EventLoop *loop; 18 | Socket *sock; 19 | Channel *channel; 20 | std::function deleteConnectionCallback; 21 | std::string *inBuffer; 22 | Buffer *readBuffer; 23 | public: 24 | Connection(EventLoop *_loop, Socket *_sock); 25 | ~Connection(); 26 | 27 | void echo(int sockfd); 28 | void setDeleteConnectionCallback(std::function); 29 | void send(int sockfd); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /code/day11/src/Epoll.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | class Channel; 12 | class Epoll 13 | { 14 | private: 15 | int epfd; 16 | struct epoll_event *events; 17 | public: 18 | Epoll(); 19 | ~Epoll(); 20 | 21 | void updateChannel(Channel*); 22 | void deleteChannel(Channel*); 23 | 24 | std::vector poll(int timeout = -1); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day11/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "EventLoop.h" 8 | #include "Epoll.h" 9 | #include "Channel.h" 10 | #include "ThreadPool.h" 11 | #include 12 | 13 | EventLoop::EventLoop() : ep(nullptr), threadPool(nullptr), quit(false){ 14 | ep = new Epoll(); 15 | threadPool = new ThreadPool(); 16 | } 17 | 18 | EventLoop::~EventLoop(){ 19 | delete threadPool; 20 | delete ep; 21 | } 22 | 23 | 24 | void EventLoop::loop(){ 25 | while(!quit){ 26 | std::vector chs; 27 | chs = ep->poll(); 28 | for(auto it = chs.begin(); it != chs.end(); ++it){ 29 | (*it)->handleEvent(); 30 | } 31 | } 32 | } 33 | 34 | void EventLoop::updateChannel(Channel *ch){ 35 | ep->updateChannel(ch); 36 | } 37 | 38 | void EventLoop::addThread(std::function func){ 39 | threadPool->add(func); 40 | } -------------------------------------------------------------------------------- /code/day11/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | /****************************** 8 | * author: yuesong-feng 9 | * 10 | * 11 | * 12 | ******************************/ 13 | #pragma once 14 | #include 15 | 16 | class Epoll; 17 | class Channel; 18 | class ThreadPool; 19 | class EventLoop 20 | { 21 | private: 22 | Epoll *ep; 23 | ThreadPool *threadPool; 24 | bool quit; 25 | public: 26 | EventLoop(); 27 | ~EventLoop(); 28 | 29 | void loop(); 30 | void updateChannel(Channel*); 31 | 32 | void addThread(std::function); 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /code/day11/src/InetAddress.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "InetAddress.h" 8 | #include 9 | 10 | InetAddress::InetAddress() { 11 | bzero(&addr, sizeof(addr)); 12 | } 13 | InetAddress::InetAddress(const char* _ip, uint16_t _port) { 14 | bzero(&addr, sizeof(addr)); 15 | addr.sin_family = AF_INET; 16 | addr.sin_addr.s_addr = inet_addr(_ip); 17 | addr.sin_port = htons(_port); 18 | } 19 | 20 | InetAddress::~InetAddress(){ 21 | } 22 | 23 | void InetAddress::setInetAddr(sockaddr_in _addr){ 24 | addr = _addr; 25 | } 26 | 27 | sockaddr_in InetAddress::getAddr(){ 28 | return addr; 29 | } 30 | -------------------------------------------------------------------------------- /code/day11/src/InetAddress.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class InetAddress 11 | { 12 | private: 13 | struct sockaddr_in addr; 14 | public: 15 | InetAddress(); 16 | InetAddress(const char* _ip, uint16_t _port); 17 | ~InetAddress(); 18 | 19 | void setInetAddr(sockaddr_in _addr); 20 | sockaddr_in getAddr(); 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /code/day11/src/Server.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | class EventLoop; 10 | class Socket; 11 | class Acceptor; 12 | class Connection; 13 | class Server 14 | { 15 | private: 16 | EventLoop *loop; 17 | Acceptor *acceptor; 18 | std::map connections; 19 | public: 20 | Server(EventLoop*); 21 | ~Server(); 22 | 23 | void handleReadEvent(int); 24 | void newConnection(Socket *sock); 25 | void deleteConnection(int sockfd); 26 | }; 27 | 28 | 29 | -------------------------------------------------------------------------------- /code/day11/src/Socket.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | 8 | #pragma once 9 | 10 | class InetAddress; 11 | class Socket 12 | { 13 | private: 14 | int fd; 15 | public: 16 | Socket(); 17 | Socket(int _fd); 18 | ~Socket(); 19 | 20 | void bind(InetAddress*); 21 | void listen(); 22 | int accept(InetAddress*); 23 | 24 | void connect(InetAddress*); 25 | 26 | void setnonblocking(); 27 | int getFd(); 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /code/day11/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day11/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day12/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "(gdb) Launch", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/server", 12 | "args": [], 13 | "stopAtEntry": false, 14 | "cwd": "${fileDirname}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "setupCommands": [ 19 | { 20 | "description": "Enable pretty-printing for gdb", 21 | "text": "-enable-pretty-printing", 22 | "ignoreFailures": true 23 | } 24 | ] 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /code/day12/Makefile: -------------------------------------------------------------------------------- 1 | src=$(wildcard src/*.cpp) 2 | 3 | server: 4 | g++ -std=c++11 -pthread -g \ 5 | $(src) \ 6 | server.cpp \ 7 | -o server 8 | 9 | client: 10 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp client.cpp -o client 11 | 12 | th: 13 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest 14 | 15 | test: 16 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp src/ThreadPool.cpp \ 17 | -pthread \ 18 | test.cpp -o test 19 | 20 | clean: 21 | rm server && rm client && rm test -------------------------------------------------------------------------------- /code/day12/ThreadPoolTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/ThreadPool.h" 4 | 5 | void print(int a, double b, const char *c, std::string d){ 6 | std::cout << a << b << c << d << std::endl; 7 | } 8 | 9 | void test(){ 10 | std::cout << "hellp" << std::endl; 11 | } 12 | 13 | int main(int argc, char const *argv[]) 14 | { 15 | ThreadPool *poll = new ThreadPool(); 16 | std::function func = std::bind(print, 1, 3.14, "hello", std::string("world")); 17 | poll->add(func); 18 | func = test; 19 | poll->add(func); 20 | delete poll; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /code/day12/server: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wlgls/30daysCppWebServer/2da77bfa53200ece7a8a43a7422b9ee38212304f/code/day12/server -------------------------------------------------------------------------------- /code/day12/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/EventLoop.h" 2 | #include "src/Server.h" 3 | 4 | int main() { 5 | EventLoop *loop = new EventLoop(); 6 | Server *server = new Server(loop); 7 | loop->loop(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /code/day12/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class EventLoop; 11 | class Socket; 12 | class Channel; 13 | class Acceptor 14 | { 15 | private: 16 | EventLoop *loop; 17 | Socket *sock; 18 | Channel *acceptChannel; 19 | std::function newConnectionCallback; 20 | public: 21 | Acceptor(EventLoop *_loop); 22 | ~Acceptor(); 23 | void acceptConnection(); 24 | void setNewConnectionCallback(std::function); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day12/src/Buffer.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "Buffer.h" 8 | #include 9 | #include 10 | Buffer::Buffer() {} 11 | 12 | Buffer::~Buffer() {} 13 | 14 | void Buffer::append(const char* _str, int _size){ 15 | for(int i = 0; i < _size; ++i){ 16 | if(_str[i] == '\0') break; 17 | buf.push_back(_str[i]); 18 | } 19 | } 20 | 21 | ssize_t Buffer::size(){ 22 | return buf.size(); 23 | } 24 | 25 | const char* Buffer::c_str(){ 26 | return buf.c_str(); 27 | } 28 | 29 | void Buffer::clear(){ 30 | buf.clear(); 31 | } 32 | 33 | void Buffer::getline(){ 34 | buf.clear(); 35 | std::getline(std::cin, buf); 36 | } 37 | 38 | void Buffer::setBuf(const char* _buf){ 39 | buf.clear(); 40 | buf.append(_buf); 41 | } -------------------------------------------------------------------------------- /code/day12/src/Buffer.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class Buffer 11 | { 12 | private: 13 | std::string buf; 14 | public: 15 | Buffer(); 16 | ~Buffer(); 17 | 18 | void append(const char* _str, int _size); 19 | ssize_t size(); 20 | const char* c_str(); 21 | void clear(); 22 | void getline(); 23 | void setBuf(const char*); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /code/day12/src/Channel.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | class Socket; 11 | class EventLoop; 12 | class Channel 13 | { 14 | private: 15 | EventLoop *loop; 16 | int fd; 17 | uint32_t events; 18 | uint32_t ready; 19 | bool inEpoll; 20 | std::function readCallback; 21 | std::function writeCallback; 22 | public: 23 | Channel(EventLoop *_loop, int _fd); 24 | ~Channel(); 25 | 26 | void handleEvent(); 27 | void enableRead(); 28 | 29 | int getFd(); 30 | uint32_t getEvents(); 31 | uint32_t getReady(); 32 | bool getInEpoll(); 33 | void setInEpoll(bool _in = true); 34 | void useET(); 35 | 36 | void setReady(uint32_t); 37 | void setReadCallback(std::function); 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /code/day12/src/Connection.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | class EventLoop; 10 | class Socket; 11 | class Channel; 12 | class Buffer; 13 | class Connection 14 | { 15 | private: 16 | EventLoop *loop; 17 | Socket *sock; 18 | Channel *channel; 19 | std::function deleteConnectionCallback; 20 | Buffer *readBuffer; 21 | public: 22 | Connection(EventLoop *_loop, Socket *_sock); 23 | ~Connection(); 24 | 25 | void echo(int sockfd); 26 | void setDeleteConnectionCallback(std::function); 27 | void send(int sockfd); 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /code/day12/src/Epoll.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | class Channel; 12 | class Epoll 13 | { 14 | private: 15 | int epfd; 16 | struct epoll_event *events; 17 | public: 18 | Epoll(); 19 | ~Epoll(); 20 | 21 | void updateChannel(Channel*); 22 | void deleteChannel(Channel*); 23 | 24 | std::vector poll(int timeout = -1); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day12/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "EventLoop.h" 8 | #include "Epoll.h" 9 | #include "Channel.h" 10 | #include 11 | 12 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 13 | ep = new Epoll(); 14 | } 15 | 16 | EventLoop::~EventLoop(){ 17 | delete ep; 18 | } 19 | 20 | 21 | void EventLoop::loop(){ 22 | while(!quit){ 23 | std::vector chs; 24 | chs = ep->poll(); 25 | for(auto it = chs.begin(); it != chs.end(); ++it){ 26 | (*it)->handleEvent(); 27 | } 28 | } 29 | } 30 | 31 | void EventLoop::updateChannel(Channel *ch){ 32 | ep->updateChannel(ch); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /code/day12/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | /****************************** 8 | * author: yuesong-feng 9 | * 10 | * 11 | * 12 | ******************************/ 13 | #pragma once 14 | #include 15 | 16 | class Epoll; 17 | class Channel; 18 | class EventLoop 19 | { 20 | private: 21 | Epoll *ep; 22 | bool quit; 23 | public: 24 | EventLoop(); 25 | ~EventLoop(); 26 | 27 | void loop(); 28 | void updateChannel(Channel*); 29 | 30 | void addThread(std::function); 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /code/day12/src/Server.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | class EventLoop; 11 | class Socket; 12 | class Acceptor; 13 | class Connection; 14 | class ThreadPool; 15 | class Server 16 | { 17 | private: 18 | EventLoop *mainReactor; 19 | Acceptor *acceptor; 20 | std::map connections; 21 | std::vector subReactors; 22 | ThreadPool *thpool; 23 | public: 24 | Server(EventLoop*); 25 | ~Server(); 26 | 27 | void handleReadEvent(int); 28 | void newConnection(Socket *sock); 29 | void deleteConnection(int sockfd); 30 | }; 31 | 32 | 33 | -------------------------------------------------------------------------------- /code/day12/src/Socket.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | 8 | #pragma once 9 | #include 10 | 11 | class InetAddress 12 | { 13 | private: 14 | struct sockaddr_in addr; 15 | public: 16 | InetAddress(); 17 | InetAddress(const char* _ip, uint16_t _port); 18 | ~InetAddress(); 19 | 20 | void setInetAddr(sockaddr_in _addr); 21 | sockaddr_in getAddr(); 22 | char* getIp(); 23 | uint16_t getPort(); 24 | }; 25 | 26 | class Socket 27 | { 28 | private: 29 | int fd; 30 | public: 31 | Socket(); 32 | Socket(int _fd); 33 | ~Socket(); 34 | 35 | void bind(InetAddress*); 36 | void listen(); 37 | int accept(InetAddress*); 38 | 39 | void connect(InetAddress*); 40 | 41 | void setnonblocking(); 42 | int getFd(); 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /code/day12/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day12/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day13/Makefile: -------------------------------------------------------------------------------- 1 | src=$(wildcard src/*.cpp) 2 | 3 | server: 4 | g++ -std=c++11 -pthread -g \ 5 | $(src) \ 6 | server.cpp \ 7 | -o server 8 | 9 | client: 10 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp client.cpp -o client 11 | 12 | th: 13 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest 14 | 15 | test: 16 | g++ src/util.cpp src/Buffer.cpp src/Socket.cpp src/InetAddress.cpp src/ThreadPool.cpp \ 17 | -pthread \ 18 | test.cpp -o test 19 | 20 | clean: 21 | rm server && rm client && rm test -------------------------------------------------------------------------------- /code/day13/ThreadPoolTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "src/ThreadPool.h" 4 | 5 | void print(int a, double b, const char *c, std::string d){ 6 | std::cout << a << b << c << d << std::endl; 7 | } 8 | 9 | void test(){ 10 | std::cout << "hellp" << std::endl; 11 | } 12 | 13 | int main(int argc, char const *argv[]) 14 | { 15 | ThreadPool *poll = new ThreadPool(); 16 | std::function func = std::bind(print, 1, 3.14, "hello", std::string("world")); 17 | poll->add(func); 18 | func = test; 19 | poll->add(func); 20 | delete poll; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /code/day13/server.cpp: -------------------------------------------------------------------------------- 1 | #include "src/Server.h" 2 | #include 3 | #include "src/Buffer.h" 4 | #include "src/Connection.h" 5 | #include "src/EventLoop.h" 6 | #include "src/Socket.h" 7 | 8 | int main() { 9 | EventLoop *loop = new EventLoop(); 10 | Server *server = new Server(loop); 11 | server->OnConnect([](Connection *conn) { 12 | conn->Read(); 13 | if (conn->GetState() == Connection::State::Closed) { 14 | conn->Close(); 15 | return; 16 | } 17 | std::cout << "Message from client " << conn->GetSocket()->getFd() << ": " << conn->ReadBuffer() << std::endl; 18 | conn->SetSendBuffer(conn->ReadBuffer()); 19 | conn->Write(); 20 | }); 21 | 22 | loop->loop(); 23 | delete server; 24 | delete loop; 25 | return 0; 26 | } -------------------------------------------------------------------------------- /code/day13/src/Acceptor.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class EventLoop; 11 | class Socket; 12 | class Channel; 13 | class Acceptor 14 | { 15 | private: 16 | EventLoop *loop; 17 | Socket *sock; 18 | Channel *acceptChannel; 19 | std::function newConnectionCallback; 20 | public: 21 | Acceptor(EventLoop *_loop); 22 | ~Acceptor(); 23 | void acceptConnection(); 24 | void setNewConnectionCallback(std::function); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day13/src/Buffer.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "Buffer.h" 8 | #include 9 | #include 10 | Buffer::Buffer() {} 11 | 12 | Buffer::~Buffer() {} 13 | 14 | void Buffer::append(const char* _str, int _size){ 15 | for(int i = 0; i < _size; ++i){ 16 | if(_str[i] == '\0') break; 17 | buf.push_back(_str[i]); 18 | } 19 | } 20 | 21 | ssize_t Buffer::size(){ 22 | return buf.size(); 23 | } 24 | 25 | const char* Buffer::c_str(){ 26 | return buf.c_str(); 27 | } 28 | 29 | void Buffer::clear(){ 30 | buf.clear(); 31 | } 32 | 33 | void Buffer::getline(){ 34 | buf.clear(); 35 | std::getline(std::cin, buf); 36 | } 37 | 38 | void Buffer::setBuf(const char* _buf){ 39 | buf.clear(); 40 | buf.append(_buf); 41 | } -------------------------------------------------------------------------------- /code/day13/src/Buffer.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | 10 | class Buffer 11 | { 12 | private: 13 | std::string buf; 14 | public: 15 | Buffer(); 16 | ~Buffer(); 17 | 18 | void append(const char* _str, int _size); 19 | ssize_t size(); 20 | const char* c_str(); 21 | void clear(); 22 | void getline(); 23 | void setBuf(const char*); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /code/day13/src/Channel.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | class Socket; 11 | class EventLoop; 12 | class Channel 13 | { 14 | private: 15 | EventLoop *loop; 16 | int fd; 17 | uint32_t events; 18 | uint32_t ready; 19 | bool inEpoll; 20 | std::function readCallback; 21 | std::function writeCallback; 22 | public: 23 | Channel(EventLoop *_loop, int _fd); 24 | ~Channel(); 25 | 26 | void handleEvent(); 27 | void enableRead(); 28 | 29 | int getFd(); 30 | uint32_t getEvents(); 31 | uint32_t getReady(); 32 | bool getInEpoll(); 33 | void setInEpoll(bool _in = true); 34 | void useET(); 35 | 36 | void setReady(uint32_t); 37 | void setReadCallback(std::function); 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /code/day13/src/Epoll.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #pragma once 8 | #include 9 | #include 10 | 11 | class Channel; 12 | class Epoll 13 | { 14 | private: 15 | int epfd; 16 | struct epoll_event *events; 17 | public: 18 | Epoll(); 19 | ~Epoll(); 20 | 21 | void updateChannel(Channel*); 22 | void deleteChannel(Channel*); 23 | 24 | std::vector poll(int timeout = -1); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /code/day13/src/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | #include "EventLoop.h" 8 | #include "Epoll.h" 9 | #include "Channel.h" 10 | #include 11 | 12 | EventLoop::EventLoop() : ep(nullptr), quit(false){ 13 | ep = new Epoll(); 14 | } 15 | 16 | EventLoop::~EventLoop(){ 17 | delete ep; 18 | } 19 | 20 | 21 | void EventLoop::loop(){ 22 | while(!quit){ 23 | std::vector chs; 24 | chs = ep->poll(); 25 | for(auto it = chs.begin(); it != chs.end(); ++it){ 26 | (*it)->handleEvent(); 27 | } 28 | } 29 | } 30 | 31 | void EventLoop::updateChannel(Channel *ch){ 32 | ep->updateChannel(ch); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /code/day13/src/EventLoop.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | /****************************** 8 | * author: yuesong-feng 9 | * 10 | * 11 | * 12 | ******************************/ 13 | #pragma once 14 | #include 15 | 16 | class Epoll; 17 | class Channel; 18 | class EventLoop 19 | { 20 | private: 21 | Epoll *ep; 22 | bool quit; 23 | public: 24 | EventLoop(); 25 | ~EventLoop(); 26 | 27 | void loop(); 28 | void updateChannel(Channel*); 29 | 30 | void addThread(std::function); 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /code/day13/src/Server.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Server.h 3 | * @author 冯岳松 (yuesong-feng@foxmail.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2022-01-04 7 | * 8 | * @copyright Copyright (冯岳松) 2022 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | #include 15 | #include 16 | class EventLoop; 17 | class Socket; 18 | class Acceptor; 19 | class Connection; 20 | class ThreadPool; 21 | class Server { 22 | private: 23 | EventLoop *main_reactor_; 24 | Acceptor *acceptor_; 25 | std::map connections_; 26 | std::vector sub_reactors_; 27 | ThreadPool *thread_pool_; 28 | std::function on_connect_callback_; 29 | 30 | public: 31 | explicit Server(EventLoop *loop); 32 | ~Server(); 33 | void NewConnection(Socket *sock); 34 | void DeleteConnection(Socket *sock); 35 | void OnConnect(std::function fn); 36 | }; -------------------------------------------------------------------------------- /code/day13/src/Socket.h: -------------------------------------------------------------------------------- 1 | /****************************** 2 | * author: yuesong-feng 3 | * 4 | * 5 | * 6 | ******************************/ 7 | 8 | #pragma once 9 | #include 10 | 11 | class InetAddress 12 | { 13 | private: 14 | struct sockaddr_in addr; 15 | public: 16 | InetAddress(); 17 | InetAddress(const char* _ip, uint16_t _port); 18 | ~InetAddress(); 19 | 20 | void setInetAddr(sockaddr_in _addr); 21 | sockaddr_in getAddr(); 22 | char* getIp(); 23 | uint16_t getPort(); 24 | }; 25 | 26 | class Socket 27 | { 28 | private: 29 | int fd; 30 | public: 31 | Socket(); 32 | Socket(int _fd); 33 | ~Socket(); 34 | 35 | void bind(InetAddress*); 36 | void listen(); 37 | int accept(InetAddress*); 38 | 39 | void connect(InetAddress*); 40 | 41 | void setnonblocking(); 42 | int getFd(); 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /code/day13/src/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | #include 3 | #include 4 | 5 | void errif(bool condition, const char *errmsg){ 6 | if(condition){ 7 | perror(errmsg); 8 | exit(EXIT_FAILURE); 9 | } 10 | } -------------------------------------------------------------------------------- /code/day13/src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef UTIL_H 2 | #define UTIL_H 3 | 4 | void errif(bool, const char*); 5 | 6 | #endif -------------------------------------------------------------------------------- /code/day14/Makefile: -------------------------------------------------------------------------------- 1 | TCP=$(wildcard tcp/*.cpp) 2 | 3 | server: 4 | g++ -std=c++14 -pthread -g \ 5 | $(TCP) \ 6 | echo_server.cpp \ 7 | -o server 8 | 9 | th: 10 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest 11 | 12 | clean: 13 | rm server 14 | -------------------------------------------------------------------------------- /code/day14/echo_server.cpp: -------------------------------------------------------------------------------- 1 | #include "tcp/Acceptor.h" 2 | #include "tcp/EventLoop.h" 3 | #include "tcp/TcpServer.h" 4 | #include "tcp/Buffer.h" 5 | #include "tcp/ThreadPool.h" 6 | #include "tcp/TcpConnection.h" 7 | #include 8 | #include 9 | 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | TcpServer *server = new TcpServer("127.0.0.1", 1234); 14 | 15 | server->set_message_callback([](TcpConnection *conn) 16 | { 17 | std::cout << "Message from client " << conn->id() << " is " << conn->read_buf()->c_str() << std::endl; 18 | conn->Send(conn->read_buf()->c_str()); }); 19 | 20 | server->Start(); 21 | 22 | delete server; 23 | return 0; 24 | } -------------------------------------------------------------------------------- /code/day14/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day14/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day14/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day14/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day14/tcp/EventLoop.cpp: -------------------------------------------------------------------------------- 1 | #include "EventLoop.h" 2 | #include 3 | #include "Channel.h" 4 | #include "Epoller.h" 5 | 6 | EventLoop::EventLoop() { poller_ = std::make_unique(); } 7 | 8 | EventLoop::~EventLoop() {} 9 | 10 | void EventLoop::Loop() const { 11 | while(true){ 12 | for (Channel *active_ch : poller_->Poll()){ 13 | active_ch->HandleEvent(); 14 | } 15 | } 16 | } 17 | 18 | void EventLoop::UpdateChannel(Channel *ch) const { poller_->UpdateChannel(ch); } 19 | void EventLoop::DeleteChannel(Channel *ch) const { poller_->DeleteChannel(ch); } -------------------------------------------------------------------------------- /code/day14/tcp/EventLoop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Epoller.h" 4 | #include "common.h" 5 | #include 6 | 7 | class Epoller; 8 | class EventLoop 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(EventLoop); 12 | EventLoop(); 13 | ~EventLoop(); 14 | 15 | void Loop() const; 16 | void UpdateChannel(Channel *ch) const; 17 | void DeleteChannel(Channel *ch) const; 18 | 19 | private: 20 | std::unique_ptr poller_; 21 | }; -------------------------------------------------------------------------------- /code/day14/tcp/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class TcpServer; 4 | class EventLoop; 5 | class Poller; 6 | class PollPoller; 7 | class Acceptor; 8 | class Connection; 9 | class Channel; 10 | class Socket; 11 | class Buffer; 12 | class ThreadPool; 13 | 14 | // Macros to disable copying and moving 15 | #define DISALLOW_COPY(cname) \ 16 | cname(const cname &) = delete; \ 17 | cname &operator=(const cname &) = delete; 18 | 19 | #define DISALLOW_MOVE(cname) \ 20 | cname(cname &&) = delete; \ 21 | cname &operator=(cname &&) = delete; 22 | 23 | #define DISALLOW_COPY_AND_MOVE(cname) \ 24 | DISALLOW_COPY(cname); \ 25 | DISALLOW_MOVE(cname); 26 | 27 | // #define ASSERT(expr, message) assert((expr) && (message)) 28 | 29 | // #define UNREACHABLE(message) throw std::logic_error(message) 30 | -------------------------------------------------------------------------------- /code/day15/Makefile: -------------------------------------------------------------------------------- 1 | TCP=$(wildcard tcp/*.cpp) 2 | 3 | server: 4 | g++ -std=c++14 -pthread -g \ 5 | $(TCP) \ 6 | echo_server.cpp \ 7 | -o server 8 | 9 | th: 10 | g++ -pthread src/ThreadPool.cpp ThreadPoolTest.cpp -o ThreadPoolTest 11 | 12 | clean: 13 | rm server 14 | -------------------------------------------------------------------------------- /code/day15/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day15/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day15/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day15/tcp/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day15/tcp/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day15/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day16/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.10) 3 | project(WebServer) 4 | 5 | 6 | include_directories( 7 | base 8 | tcp 9 | ) 10 | 11 | SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++14") 12 | set(CMAKE_CXX_COMPILER "g++") 13 | set(CMAKE_CXX_FLAGS_DEBUG "-O0") 14 | 15 | find_package(Threads REQUIRED) 16 | 17 | aux_source_directory(base SRC_LIST1) 18 | aux_source_directory(tcp SRC_LIST2) 19 | 20 | 21 | set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/test/) 22 | 23 | add_executable(echoserver test/echo_server.cpp ${SRC_LIST1} ${SRC_LIST2} ) 24 | target_link_libraries(echoserver ${CMAKE_THREAD_LIBS_INIT}) 25 | 26 | -------------------------------------------------------------------------------- /code/day16/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day16/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day16/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day16/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day16/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day16/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day17/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.10) 3 | project(WebServer) 4 | 5 | 6 | include_directories( 7 | base 8 | tcp 9 | ) 10 | 11 | SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++14") 12 | set(CMAKE_CXX_COMPILER "g++") 13 | set(CMAKE_CXX_FLAGS_DEBUG "-O0") 14 | 15 | find_package(Threads REQUIRED) 16 | 17 | aux_source_directory(base SRC_LIST1) 18 | aux_source_directory(tcp SRC_LIST2) 19 | 20 | 21 | set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/test/) 22 | 23 | add_executable(echoserver test/echo_server.cpp ${SRC_LIST1} ${SRC_LIST2} ) 24 | target_link_libraries(echoserver ${CMAKE_THREAD_LIBS_INIT}) 25 | 26 | -------------------------------------------------------------------------------- /code/day17/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day17/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day17/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day17/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day17/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day17/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day17/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day17/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day18/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.10) 3 | project(WebServer) 4 | 5 | 6 | include_directories( 7 | base 8 | tcp 9 | http 10 | ) 11 | 12 | SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++14") 13 | set(CMAKE_CXX_COMPILER "g++") 14 | set(CMAKE_CXX_FLAGS_DEBUG "-O0") 15 | 16 | find_package(Threads REQUIRED) 17 | 18 | aux_source_directory(base SRC_LIST1) 19 | aux_source_directory(tcp SRC_LIST2) 20 | aux_source_directory(http SRC_LIST3) 21 | 22 | 23 | set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/test/) 24 | 25 | add_executable(echoserver test/echo_server.cpp ${SRC_LIST1} ${SRC_LIST2} ) 26 | add_executable(test_context test/test_httpcontext.cpp ${SRC_LIST3} ) 27 | target_link_libraries(echoserver ${CMAKE_THREAD_LIBS_INIT}) 28 | 29 | -------------------------------------------------------------------------------- /code/day18/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day18/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day18/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day18/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day18/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day18/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day18/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day18/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day19/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.10) 3 | project(WebServer) 4 | 5 | 6 | include_directories( 7 | base 8 | tcp 9 | http 10 | ) 11 | 12 | SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++14") 13 | set(CMAKE_CXX_COMPILER "g++") 14 | set(CMAKE_CXX_FLAGS_DEBUG "-O0") 15 | 16 | find_package(Threads REQUIRED) 17 | 18 | aux_source_directory(base SRC_LIST1) 19 | aux_source_directory(tcp SRC_LIST2) 20 | aux_source_directory(http SRC_LIST3) 21 | 22 | 23 | set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/test/) 24 | 25 | add_executable(webserver test/http_server.cpp ${SRC_LIST1} ${SRC_LIST2} ${SRC_LIST3} ) 26 | #add_executable(echoserver test/echo_server.cpp ${SRC_LIST1} ${SRC_LIST2} ) 27 | #add_executable(test_context test/test_httpcontext.cpp ${SRC_LIST3} ) 28 | # target_link_libraries(echoserver ${CMAKE_THREAD_LIBS_INIT}) 29 | target_link_libraries(webserver ${CMAKE_THREAD_LIBS_INIT}) 30 | 31 | -------------------------------------------------------------------------------- /code/day19/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day19/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day19/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day19/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day19/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day19/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day19/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day19/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day20/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day20/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day20/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day20/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day20/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day20/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day20/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day20/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day20/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day20/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day21/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day21/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day21/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day21/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day21/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day21/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day21/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day21/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day21/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day21/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day22/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day22/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day22/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day22/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day22/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day22/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day22/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day22/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day22/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day22/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day22/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day23/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day23/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day23/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day23/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day23/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day23/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day23/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day23/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day23/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day23/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day23/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day24/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day24/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day24/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day24/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day24/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day24/tcp/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "Buffer.h" 2 | 3 | const std::string &Buffer::buf() const { return buf_; } 4 | 5 | const char *Buffer::c_str() const { return buf_.c_str(); } 6 | 7 | void Buffer::set_buf(const char *buf) { 8 | std::string new_buf(buf); 9 | buf_.swap(new_buf); 10 | } 11 | 12 | size_t Buffer::Size() const { return buf_.size(); } 13 | 14 | void Buffer::Append(const char *str, int size) { 15 | for (int i = 0; i < size; ++i) { 16 | if (str[i] == '\0') { 17 | break; 18 | } 19 | buf_.push_back(str[i]); 20 | } 21 | } 22 | 23 | void Buffer::Clear() { buf_.clear(); } -------------------------------------------------------------------------------- /code/day24/tcp/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "common.h" 6 | 7 | class Buffer{ 8 | public: 9 | DISALLOW_COPY_AND_MOVE(Buffer); 10 | Buffer() = default; 11 | ~Buffer() = default; 12 | 13 | const std::string &buf() const; 14 | const char *c_str() const; 15 | 16 | void set_buf(const char *buf); 17 | 18 | size_t Size() const; 19 | void Append(const char *_str, int _size); 20 | void Clear(); 21 | 22 | private: 23 | std::string buf_; 24 | }; -------------------------------------------------------------------------------- /code/day24/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day24/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day24/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day24/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day24/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day24/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day25/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day25/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day25/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day25/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day25/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day25/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day25/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day25/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day25/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day25/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day25/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day26/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day26/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day26/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day26/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day26/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day26/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day26/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day26/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day26/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day26/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day26/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day27/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day27/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day27/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day27/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day27/static/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wlgls/30daysCppWebServer/2da77bfa53200ece7a8a43a7422b9ee38212304f/code/day27/static/cat.jpg -------------------------------------------------------------------------------- /code/day27/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sign up 6 | 7 | 8 |
9 |
10 |
注册/登陆
11 |
12 | 19 | 20 |
21 | 22 | -------------------------------------------------------------------------------- /code/day27/static/mhw.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Welcome MHW!

4 |

5 | 6 | -------------------------------------------------------------------------------- /code/day27/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day27/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day27/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day27/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day27/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day27/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day27/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day28/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day28/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day28/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day28/files/a.txt: -------------------------------------------------------------------------------- 1 | a;;;asdkljhgasdkljfalskjgkldasfhjklashdgkdjsafhjklasdfglkadsjg -------------------------------------------------------------------------------- /code/day28/files/b.txt: -------------------------------------------------------------------------------- 1 | b -------------------------------------------------------------------------------- /code/day28/files/c.txt: -------------------------------------------------------------------------------- 1 | c -------------------------------------------------------------------------------- /code/day28/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day28/static/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wlgls/30daysCppWebServer/2da77bfa53200ece7a8a43a7422b9ee38212304f/code/day28/static/cat.jpg -------------------------------------------------------------------------------- /code/day28/static/mhw.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Welcome MHW!

4 |

5 | 6 | -------------------------------------------------------------------------------- /code/day28/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day28/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day28/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day28/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day28/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day28/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day28/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /code/day29/base/CurrentThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "CurrentThread.h" 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | __thread int t_cachedTid = 0; 9 | __thread char t_formattedTid[32]; 10 | __thread int t_formattedTidLength; 11 | 12 | pid_t gettid() { 13 | // 不使用std::this_thread::get_id(),它好像并不是唯一的 14 | return static_cast(syscall(SYS_gettid)); 15 | } 16 | void CacheTid(){ 17 | if (t_cachedTid == 0){ 18 | t_cachedTid = gettid(); 19 | t_formattedTidLength = snprintf(t_formattedTid, sizeof(t_formattedTid), "%5d ", t_cachedTid); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /code/day29/base/CurrentThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | namespace CurrentThread 7 | { 8 | extern __thread int t_cachedTid; 9 | extern __thread char t_formattedTid[32]; 10 | extern __thread int t_formattedTidLength; 11 | 12 | void CacheTid(); 13 | 14 | pid_t gettid(); 15 | 16 | inline int tid() { 17 | if (__builtin_expect(t_cachedTid == 0, 0)) { 18 | CacheTid(); 19 | } 20 | return t_cachedTid; 21 | } 22 | 23 | 24 | inline const char *tidString() { return t_formattedTid; } 25 | inline int tidStringLength() { return t_formattedTidLength; } 26 | } -------------------------------------------------------------------------------- /code/day29/base/Latch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | #include 4 | #include 5 | class Latch 6 | { 7 | private: 8 | std::mutex mux_; 9 | std::condition_variable cv_; 10 | int count_; 11 | 12 | public: 13 | DISALLOW_COPY_AND_MOVE(Latch); 14 | 15 | explicit Latch(int count) : count_(count){} 16 | void wait(){ 17 | std::unique_lock lock(mux_); 18 | while(count_ > 0){ 19 | cv_.wait(lock); 20 | } 21 | } 22 | 23 | void notify(){ 24 | std::unique_lock lock(mux_); 25 | --count_; 26 | if(count_ == 0){ 27 | cv_.notify_all(); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /code/day29/files/a.txt: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /code/day29/files/b.txt: -------------------------------------------------------------------------------- 1 | b -------------------------------------------------------------------------------- /code/day29/files/c.txt: -------------------------------------------------------------------------------- 1 | c -------------------------------------------------------------------------------- /code/day29/files/d.txt: -------------------------------------------------------------------------------- 1 | d 2 | -------------------------------------------------------------------------------- /code/day29/log/LogFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TimeStamp.h" 8 | 9 | static const time_t FlushInterval = 3; 10 | 11 | class LogFile{ 12 | public: 13 | LogFile(const char *filepath=nullptr); 14 | ~LogFile(); 15 | 16 | void Write(const char *data, int len); 17 | 18 | void Flush(); 19 | 20 | int64_t writtenbytes() const; 21 | private: 22 | FILE *fp_; 23 | int64_t written_bytes_; 24 | time_t lastwrite_; 25 | time_t lastflush_; 26 | }; -------------------------------------------------------------------------------- /code/day29/static/cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Wlgls/30daysCppWebServer/2da77bfa53200ece7a8a43a7422b9ee38212304f/code/day29/static/cat.jpg -------------------------------------------------------------------------------- /code/day29/static/mhw.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Welcome MHW!

4 |

5 | 6 | -------------------------------------------------------------------------------- /code/day29/tcp/Acceptor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class EventLoop; 8 | class Channel; 9 | 10 | class Acceptor{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(Acceptor); 13 | Acceptor(EventLoop *loop, const char * ip, const int port); 14 | ~Acceptor(); 15 | 16 | void set_newconnection_callback(std::function const &callback); 17 | 18 | // 创建socket 19 | void Create(); 20 | 21 | // 与ip地址绑定 22 | void Bind(const char *ip, const int port); 23 | 24 | // 监听Socket 25 | void Listen(); 26 | 27 | // 接收连接 28 | void AcceptConnection(); 29 | 30 | private: 31 | EventLoop *loop_; 32 | int listenfd_; 33 | std::unique_ptr channel_; 34 | std::function new_connection_callback_; 35 | }; 36 | -------------------------------------------------------------------------------- /code/day29/tcp/Epoller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | 7 | class Channel; 8 | class Epoller 9 | { 10 | public: 11 | DISALLOW_COPY_AND_MOVE(Epoller); 12 | 13 | Epoller(); 14 | ~Epoller(); 15 | 16 | // 更新监听的channel 17 | void UpdateChannel(Channel *ch) const; 18 | // 删除监听的通道 19 | void DeleteChannel(Channel *ch) const; 20 | 21 | // 返回调用完epoll_wait的通道事件 22 | std::vector Poll(long timeout = -1) const; 23 | 24 | private: 25 | int fd_; 26 | struct epoll_event *events_; 27 | }; -------------------------------------------------------------------------------- /code/day29/tcp/EventLoopThread.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class EventLoop; 9 | 10 | class EventLoopThread{ 11 | public: 12 | DISALLOW_COPY_AND_MOVE(EventLoopThread) 13 | EventLoopThread(); 14 | ~EventLoopThread(); 15 | 16 | // 启动线程, 使EventLoop成为IO线程 17 | EventLoop *StartLoop(); 18 | 19 | private: 20 | // 线程运行的函数 21 | void ThreadFunc(); 22 | 23 | // 指向由子线程创建的的EventLoop,用于主线程和子线程的数据传递 24 | EventLoop *loop_; 25 | std::thread thread_; 26 | std::mutex mutex_; 27 | std::condition_variable cv_; 28 | }; -------------------------------------------------------------------------------- /code/day29/tcp/EventLoopThreadPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | class EventLoop; 10 | class EventLoopThread; 11 | 12 | class EventLoopThreadPool{ 13 | 14 | public: 15 | DISALLOW_COPY_AND_MOVE(EventLoopThreadPool); 16 | EventLoopThreadPool(EventLoop *loop); 17 | ~EventLoopThreadPool(); 18 | 19 | void SetThreadNums(int thread_nums); 20 | 21 | void start(); 22 | 23 | // 获取线程池中的EventLoop 24 | EventLoop *nextloop(); 25 | 26 | private: 27 | EventLoop *main_reactor_; 28 | std::vector> threads_; 29 | 30 | std::vector loops_; 31 | 32 | int thread_nums_; 33 | 34 | int next_; 35 | }; -------------------------------------------------------------------------------- /code/day29/test/test_logstream.cpp: -------------------------------------------------------------------------------- 1 | #include "LogStream.h" 2 | #include 3 | int main(){ 4 | 5 | LogStream os; 6 | os << "hello world"; 7 | std::cout << os.buffer().data() << std::endl; 8 | os.resetBuffer(); 9 | 10 | os << 11; 11 | std::cout << os.buffer().data() << std::endl; 12 | os.resetBuffer(); 13 | 14 | os << 0.1; 15 | std::cout << os.buffer().data() << std::endl; 16 | os.resetBuffer(); 17 | 18 | os << Fmt("%0.5f", 0.1); 19 | std::cout << os.buffer().data() << std::endl; 20 | os.resetBuffer(); 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code/day29/timer/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "Timer.h" 2 | #include 3 | #include "TimeStamp.h" 4 | Timer::Timer(TimeStamp timestamp, std::functionconst &cb, double interval = 0.0) 5 | : expiration_(timestamp), 6 | callback_(std::move(cb)), 7 | interval_(interval), 8 | repeat_(interval > 0.0){}; 9 | 10 | void Timer::ReStart(TimeStamp now){ 11 | expiration_ = TimeStamp::AddTime(now, interval_); 12 | } 13 | 14 | 15 | void Timer::run() const{ 16 | callback_(); 17 | } 18 | 19 | TimeStamp Timer::expiration() const { return expiration_; } 20 | 21 | bool Timer::repeat() const { return repeat_; } 22 | 23 | 24 | -------------------------------------------------------------------------------- /code/day29/timer/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "common.h" 4 | #include "TimeStamp.h" 5 | class Timer 6 | { 7 | public: 8 | DISALLOW_COPY_AND_MOVE(Timer); 9 | Timer(TimeStamp timestamp, std::functionconst &cb, double interval); 10 | 11 | void ReStart(TimeStamp now); 12 | 13 | void run() const; 14 | TimeStamp expiration() const; 15 | bool repeat() const; 16 | 17 | private: 18 | TimeStamp expiration_; // 定时器的绝对时间 19 | std::function callback_; // 到达时间后进行回调 20 | double interval_; // 如果重复,则重复间隔 21 | bool repeat_; 22 | }; -------------------------------------------------------------------------------- /day30-WebBench的测试.md: -------------------------------------------------------------------------------- 1 | # day30-WebBench的测试 2 | 3 | 关于WebBench的话,网络有许多教程,[官网](http://home.tiscali.cz/~cz210552/webbench.html) 4 | 5 | 测试时,运行当前服务器,并使用webbench命令即可。 6 | 7 | ```shell 8 | ➜ ~ webbench -c 10000 -t 5 http://127.0.0.1:1236/ 9 | Webbench - Simple Web Benchmark 1.5 10 | Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software. 11 | 12 | Benchmarking: GET http://127.0.0.1:1236/ 13 | 10000 clients, running 5 sec. 14 | 15 | Speed=3010200 pages/min, 57294136 bytes/sec. 16 | Requests: 250850 susceed, 0 failed. 17 | ``` 18 | 19 | 大概就这样,更改客户端数量和时间和连接来测试不同的情况即可。 --------------------------------------------------------------------------------