-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTcpListener.cpp
More file actions
77 lines (71 loc) · 1.76 KB
/
Copy pathTcpListener.cpp
File metadata and controls
77 lines (71 loc) · 1.76 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
67
68
69
70
71
72
73
74
75
76
77
#include "TcpListener.h"
#include "Core/Logger.h"
#include "Core/ThreadSyncManager.h"
#include <asio.hpp>
namespace sh::network
{
struct TcpListener::Impl
{
asio::ip::tcp::acceptor acceptor;
};
TcpListener::TcpListener(const NetworkContext& ctx)
{
asio::io_context& ioCtx = *reinterpret_cast<asio::io_context*>(ctx.GetNativeHandle());
asio::ip::tcp::acceptor acceptor{ ioCtx };
impl = std::make_unique<Impl>(Impl{ std::move(acceptor) });
}
TcpListener::~TcpListener()
{
impl->acceptor.close();
}
SH_NET_API auto TcpListener::Listen(uint16_t port) -> bool
{
impl->acceptor.open(asio::ip::tcp::v4());
asio::error_code err;
impl->acceptor.bind(asio::ip::tcp::endpoint{ asio::ip::tcp::v4(), port }, err);
if (err)
{
SH_ERROR_FORMAT("Error to bind: {}", err.message());
return false;
}
impl->acceptor.listen(asio::socket_base::max_listen_connections, err);
if (err)
{
SH_ERROR_FORMAT("Error to listen: {}", err.message());
return false;
}
Accept();
return true;
}
SH_NET_API auto TcpListener::GetJoinedSocket() -> std::optional<TcpSocket>
{
if (!mu.try_lock())
return {};
std::lock_guard<std::mutex> lock{ mu, std::adopt_lock };
if (joinedSocket.empty())
return {};
TcpSocket sock{ std::move(joinedSocket.front()) };
joinedSocket.pop();
return sock;
}
void TcpListener::Accept()
{
impl->acceptor.async_accept(
[this](asio::error_code ec, asio::ip::tcp::socket socket)
{
if (ec)
{
SH_ERROR_FORMAT("Failed to accept: {}", ec.message());
if (ec == asio::error::basic_errors::operation_aborted)
return;
}
else
{
std::lock_guard<std::mutex> lock{ mu };
joinedSocket.push(TcpSocket{ (void*)(&socket) });
}
Accept(); // 계속 받기
}
);
}
}//namespace