-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtcpserver.cpp
More file actions
66 lines (52 loc) · 2.25 KB
/
tcpserver.cpp
File metadata and controls
66 lines (52 loc) · 2.25 KB
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
#include "tcpserver.hpp"
#include "eventbase.hpp"
TcpServer::TcpServer(EventBase* base, const ULONG ip, int port) : base_(base) {
listener_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SetNonblock(listener_);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(ip);
addr.sin_port = htons(port);
bind(listener_, (SOCKADDR*)&addr, sizeof(addr));
listen(listener_, SOMAXCONN);
channel_ = std::make_unique<Channel>(base_, listener_, [this](DWORD bytes) {
(void)bytes;
this->OnAccept();
});
client_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(client_, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&listener_, sizeof(&listener_));
SetNonblock(client_);
LaunchAccept();
}
void TcpServer::OnRead(const TcpConnection::SPtr& conn, std::string_view buffer) { read_cb_(conn, buffer); }
void TcpServer::OnAccept() {
std::cout << "on accept" << std::endl;
auto id = seed_++;
auto conn = std::make_shared<TcpConnection>(base_, client_, id);
conn->SetReadCb([this](const TcpConnection::SPtr& conn, std::string_view buffer) { OnRead(conn, buffer); });
conn->SetCloseCb([this](const TcpConnection::SPtr& conn) { OnClose(conn); });
connections_[id] = conn;
// SetFileCompletionNotificationModes((HANDLE)client_, FILE_SKIP_COMPLETION_PORT_ON_SUCCESS);
client_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(client_, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&listener_, sizeof(&listener_));
SetNonblock(client_);
conn->LaunchRead();
LaunchAccept();
}
void TcpServer::LaunchAccept() {
char addrbuf[1];
DWORD pending = 0;
ZeroMemory(&overlapped_, sizeof(OVERLAPPED));
CHECK(lpfnAcceptEx != NULL, "empty lpfnAcceptEx");
WSASetLastError(0);
auto res = lpfnAcceptEx((SOCKET)channel_->Handle(), client_, addrbuf, 0, sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16, &pending, &overlapped_);
std::cout << "launch accept res = " << res << " handle = " << (uint64_t)channel_->Handle()
<< " client handle = " << (uint64_t)client_ << std::endl;
if (res) {
std::cout << "impossible" << std::endl;
} else {
auto err = WSAGetLastError();
CHECK(err == ERROR_IO_PENDING, err);
}
}