-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcp_server.cc
110 lines (97 loc) · 2.55 KB
/
tcp_server.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "tcp_server.h"
#include "config.h"
namespace sylar {
static Logger::ptr g_logger = SYLAR_LOG_NAME("system");
static ConfigVar<uint64_t>::ptr g_tcp_server_read_timeout =
sylar::Config::Lookup("tcp_sever.read_timeout", (uint64_t)(60 * 1000 * 2), "tcp server read timeout");
TcpServer::TcpServer(sylar::IOManager* worker
,sylar::IOManager* io_worker
,sylar::IOManager* accept_worker)
:m_worker(worker)
,m_ioWorker(io_worker)
,m_accept_worker(accept_worker)
,m_recvTimeout(g_tcp_server_read_timeout->getValue())
,m_name("sylar/1.0.0")
,m_isStop(true) {
}
bool TcpServer::bind(sylar::Address::ptr addr) {
std::vector<Address::ptr> addrs;
std::vector<Address::ptr> fails;
addrs.push_back(addr);
return bind(addrs, fails);
}
TcpServer::~TcpServer() {
for(auto& i : m_socks) {
i->close();
}
m_socks.clear();
}
bool TcpServer::bind(const std::vector<Address::ptr>& addrs
,std::vector<Address::ptr>& fails) {
for(auto& addr : addrs) {
Socket::ptr sock = Socket::CreateTCP(addr);
if(!sock->bind(addr)) {
SYLAR_LOG_ERROR(g_logger) << "bind fail error="
<< errno << "errstr=" << strerror(errno)
<< " addr=(" << addr->toString() << ")";
fails.push_back(addr);
break;
}
if(!sock->listen()) {
SYLAR_LOG_ERROR(g_logger) << "listen fail errno="
<< errno << " errstr=" << strerror(errno)
<< " addr=[" << addr->toString() << "]";
fails.push_back(addr);
continue;
}
m_socks.push_back(sock);
}
if(!fails.empty()) {
m_socks.clear();
return false;
}
for(auto& i : m_socks) {
SYLAR_LOG_INFO(g_logger) << " name = " << m_name
<< "server bind success: " << *i;
}
return true;
}
bool TcpServer::start() {
if(!m_isStop) {
return true;
}
m_isStop = false;
for(auto& sock : m_socks) {
m_accept_worker->scheduler(std::bind(&TcpServer::startAccept,
shared_from_this(), sock));
}
return true;
}
void TcpServer::stop() {
m_isStop = true;
auto self = shared_from_this();
m_accept_worker->scheduler([this, self]() {
for(auto& sock : m_socks) {
sock->cancelAll();
sock->close();
}
m_socks.clear();
});
}
void TcpServer::handleClient(Socket::ptr client) {
SYLAR_LOG_INFO(g_logger) << "handleClient: " << *client;
}
void TcpServer::startAccept(Socket::ptr sock) {
while(!m_isStop) {
Socket::ptr client = sock->accept();
if(client) {
client->setRecvTimeout(m_recvTimeout);
m_ioWorker->scheduler(std::bind(&TcpServer::handleClient,
shared_from_this(), client));
} else {
SYLAR_LOG_ERROR(g_logger) << "accept errno=" << errno
<< " errstr=" << strerror(errno);
}
}
}
}