TCPServer模块
TCPServer
模块是采用Template Pattern
设计模式封装了一个常规TCP
服务器。支持同时绑定多个地址进行监听,只需要在绑定时传入地址数组即可。还可以分别指定接收客户端和处理客户端的协程调度器
github
https://github.com/huxiaohei/tiger.git
实现
初始化TCPServer
时需要制定两个IO
调度器,分别用于接受客户端和处理客户端请求。在接受到客户端连接请求时,生成对应的客户端Socket
实例(前面在接受Socket模块的时候已经介绍过,Socket所对应的sock会在IO调度器中注册读写事件),并将Socket实例交由handle_client
处理
因此,使用TCPServer
时,必须从TCPServer
派生一个新类,并重新实现子类的handle_client
使用可以参考EchoServer
class EchoServer : public tiger::TCPServer {
public:
void handle_client(tiger::Socket::ptr client) override {
TIGER_LOG_D(tiger::TEST_LOG) << "[handle client:" << client << "]";
auto buf = std::make_shared<tiger::ByteArray>();
while (true) {
buf->clear();
std::vector<iovec> iovs;
buf->get_enable_write_buffers(iovs, 1024);
int rt = client->recv(&iovs[0], iovs.size());
if (rt == 0) {
TIGER_LOG_I(tiger::TEST_LOG) << "[has closed client:" << client << "]";
break;
} else if (rt < 0) {
TIGER_LOG_E(tiger::TEST_LOG) << "[client error"
<< " erron:" << strerror(errno) << "]";
break;
}
buf->set_position(buf->get_position() + rt);
buf->set_position(0);
const std::string &msg = buf->to_string();
TIGER_LOG_D(tiger::TEST_LOG) << "[Echo receive: " << msg << "]";
client->send(msg.c_str(), msg.size());
if (msg.find("stop") == 0) {
TIGER_LOG_I(tiger::TEST_LOG) << "[ECHO STOP]";
stop();
tiger::IOManager::GetThreadIOM()->stop();
}
}
}
};
void run() {
auto addr = tiger::Address::LookupAny("0.0.0.0:8080");
auto ech_server = std::make_shared<EchoServer>();
ech_server->bind(addr);
ech_server->start();
}
int main() {
tiger::SingletonLoggerMgr::Instance()->add_loggers("tiger", "../conf/tiger.yml");
tiger::Thread::SetName("TCPServer");
TIGER_LOG_D(tiger::TEST_LOG) << "[tcp_server test start]";
auto iom = std::make_shared<tiger::IOManager>("TCPServer", true, 1);
iom->schedule(run);
iom->start();
TIGER_LOG_D(tiger::TEST_LOG) << "[tcp_server test end]";
return 0;
}