Browse Source

Fix network: creating and joining

pull/436/head^2
Xadhoom 6 years ago committed by Anders Jenbo
parent
commit
0010c9307f
  1. 1
      CMakeLists.txt
  2. 9
      SourceX/dvlnet/abstract_net.cpp
  3. 22
      SourceX/dvlnet/abstract_net.h
  4. 23
      SourceX/dvlnet/base.cpp
  5. 16
      SourceX/dvlnet/base.h
  6. 1
      SourceX/dvlnet/cdwrap.cpp
  7. 155
      SourceX/dvlnet/cdwrap.h
  8. 24
      SourceX/dvlnet/tcp_client.cpp
  9. 5
      SourceX/dvlnet/tcp_client.h
  10. 44
      SourceX/dvlnet/tcp_server.cpp
  11. 7
      SourceX/dvlnet/tcp_server.h

1
CMakeLists.txt

@ -232,6 +232,7 @@ set(devilutionx_SRCS
SourceX/dvlnet/packet.cpp SourceX/dvlnet/packet.cpp
SourceX/dvlnet/base.cpp SourceX/dvlnet/base.cpp
SourceX/dvlnet/frame_queue.cpp SourceX/dvlnet/frame_queue.cpp
SourceX/dvlnet/cdwrap.cpp
SourceX/DiabloUI/art_draw.cpp SourceX/DiabloUI/art_draw.cpp
SourceX/DiabloUI/errorart.cpp SourceX/DiabloUI/errorart.cpp
SourceX/DiabloUI/art.cpp SourceX/DiabloUI/art.cpp

9
SourceX/dvlnet/abstract_net.cpp

@ -2,6 +2,7 @@
#include "stubs.h" #include "stubs.h"
#ifndef NONET #ifndef NONET
#include "dvlnet/cdwrap.h"
#include "dvlnet/tcp_client.h" #include "dvlnet/tcp_client.h"
#include "dvlnet/udp_p2p.h" #include "dvlnet/udp_p2p.h"
#endif #endif
@ -10,10 +11,6 @@
namespace dvl { namespace dvl {
namespace net { namespace net {
abstract_net::~abstract_net()
{
}
std::unique_ptr<abstract_net> abstract_net::make_net(provider_t provider) std::unique_ptr<abstract_net> abstract_net::make_net(provider_t provider)
{ {
#ifdef NONET #ifdef NONET
@ -21,10 +18,10 @@ std::unique_ptr<abstract_net> abstract_net::make_net(provider_t provider)
#else #else
switch (provider) { switch (provider) {
case SELCONN_TCP: case SELCONN_TCP:
return std::unique_ptr<abstract_net>(new tcp_client); return std::unique_ptr<abstract_net>(new cdwrap<tcp_client>);
#ifdef BUGGY #ifdef BUGGY
case SELCONN_UDP: case SELCONN_UDP:
return std::unique_ptr<abstract_net>(new udp_p2p); return std::unique_ptr<abstract_net>(new cdwrap<udp_p2p>);
#endif #endif
case SELCONN_LOOPBACK: case SELCONN_LOOPBACK:
return std::unique_ptr<abstract_net>(new loopback); return std::unique_ptr<abstract_net>(new loopback);

22
SourceX/dvlnet/abstract_net.h

@ -20,28 +20,28 @@ public:
virtual int create(std::string addrstr, std::string passwd) = 0; virtual int create(std::string addrstr, std::string passwd) = 0;
virtual int join(std::string addrstr, std::string passwd) = 0; virtual int join(std::string addrstr, std::string passwd) = 0;
virtual bool SNetReceiveMessage(int *sender, char **data, virtual bool SNetReceiveMessage(int *sender, char **data,
int *size) int *size)
= 0; = 0;
virtual bool SNetSendMessage(int dest, void *data, virtual bool SNetSendMessage(int dest, void *data,
unsigned int size) unsigned int size)
= 0; = 0;
virtual bool SNetReceiveTurns(char **data, unsigned int *size, virtual bool SNetReceiveTurns(char **data, unsigned int *size,
DWORD *status) DWORD *status)
= 0; = 0;
virtual bool SNetSendTurn(char *data, unsigned int size) = 0; virtual bool SNetSendTurn(char *data, unsigned int size) = 0;
virtual int SNetGetProviderCaps(struct _SNETCAPS *caps) = 0; virtual int SNetGetProviderCaps(struct _SNETCAPS *caps) = 0;
virtual bool SNetRegisterEventHandler(event_type evtype, virtual bool SNetRegisterEventHandler(event_type evtype,
SEVTHANDLER func) SEVTHANDLER func)
= 0; = 0;
virtual bool SNetUnregisterEventHandler(event_type evtype, virtual bool SNetUnregisterEventHandler(event_type evtype,
SEVTHANDLER func) SEVTHANDLER func)
= 0; = 0;
virtual bool SNetLeaveGame(int type) = 0; virtual bool SNetLeaveGame(int type) = 0;
virtual bool SNetDropPlayer(int playerid, DWORD flags) = 0; virtual bool SNetDropPlayer(int playerid, DWORD flags) = 0;
virtual bool SNetGetOwnerTurnsWaiting(DWORD *turns) = 0; virtual bool SNetGetOwnerTurnsWaiting(DWORD *turns) = 0;
virtual bool SNetGetTurnsInTransit(int *turns) = 0; virtual bool SNetGetTurnsInTransit(int *turns) = 0;
virtual void setup_gameinfo(buffer_t info) = 0; virtual void setup_gameinfo(buffer_t info) = 0;
virtual ~abstract_net(); virtual ~abstract_net() = default;
static std::unique_ptr<abstract_net> make_net(provider_t provider); static std::unique_ptr<abstract_net> make_net(provider_t provider);
}; };

23
SourceX/dvlnet/base.cpp

@ -9,7 +9,6 @@ namespace net {
void base::setup_gameinfo(buffer_t info) void base::setup_gameinfo(buffer_t info)
{ {
game_init_info = std::move(info); game_init_info = std::move(info);
pktfty.reset(new packet_factory());
} }
void base::setup_password(std::string pw) void base::setup_password(std::string pw)
@ -48,11 +47,11 @@ void base::handle_accept(packet &pkt)
void base::clear_msg(plr_t plr) void base::clear_msg(plr_t plr)
{ {
message_queue.erase(std::remove_if(message_queue.begin(), message_queue.erase(std::remove_if(message_queue.begin(),
message_queue.end(), message_queue.end(),
[&](message_t &msg) { [&](message_t &msg) {
return msg.sender == plr; return msg.sender == plr;
}), }),
message_queue.end()); message_queue.end());
} }
void base::recv_local(packet &pkt) void base::recv_local(packet &pkt)
@ -113,7 +112,7 @@ bool base::SNetReceiveMessage(int *sender, char **data, int *size)
bool base::SNetSendMessage(int playerID, void *data, unsigned int size) bool base::SNetSendMessage(int playerID, void *data, unsigned int size)
{ {
if (playerID != SNPLAYER_ALL && playerID != SNPLAYER_OTHERS if (playerID != SNPLAYER_ALL && playerID != SNPLAYER_OTHERS
&& (playerID < 0 || playerID >= MAX_PLRS)) && (playerID < 0 || playerID >= MAX_PLRS))
abort(); abort();
auto raw_message = reinterpret_cast<unsigned char *>(data); auto raw_message = reinterpret_cast<unsigned char *>(data);
buffer_t message(raw_message, raw_message + size); buffer_t message(raw_message, raw_message + size);
@ -190,7 +189,7 @@ int base::SNetGetProviderCaps(struct _SNETCAPS *caps)
caps->latencyms = 0; // unused caps->latencyms = 0; // unused
caps->defaultturnssec = 10; // ? caps->defaultturnssec = 10; // ?
caps->defaultturnsintransit = 1; // maximum acceptable number caps->defaultturnsintransit = 1; // maximum acceptable number
// of turns in queue? // of turns in queue?
return 1; return 1;
} }
@ -217,7 +216,7 @@ bool base::SNetRegisterEventHandler(event_type evtype, SEVTHANDLER func)
bool base::SNetLeaveGame(int type) bool base::SNetLeaveGame(int type)
{ {
auto pkt = pktfty->make_packet<PT_DISCONNECT>(plr_self, PLR_BROADCAST, auto pkt = pktfty->make_packet<PT_DISCONNECT>(plr_self, PLR_BROADCAST,
plr_self, type); plr_self, type);
send(*pkt); send(*pkt);
return true; return true;
} }
@ -225,9 +224,9 @@ bool base::SNetLeaveGame(int type)
bool base::SNetDropPlayer(int playerid, DWORD flags) bool base::SNetDropPlayer(int playerid, DWORD flags)
{ {
auto pkt = pktfty->make_packet<PT_DISCONNECT>(plr_self, auto pkt = pktfty->make_packet<PT_DISCONNECT>(plr_self,
PLR_BROADCAST, PLR_BROADCAST,
(plr_t)playerid, (plr_t)playerid,
(leaveinfo_t)flags); (leaveinfo_t)flags);
send(*pkt); send(*pkt);
recv_local(*pkt); recv_local(*pkt);
return true; return true;

16
SourceX/dvlnet/base.h

@ -29,13 +29,13 @@ public:
virtual bool SNetReceiveMessage(int *sender, char **data, int *size); virtual bool SNetReceiveMessage(int *sender, char **data, int *size);
virtual bool SNetSendMessage(int dest, void *data, unsigned int size); virtual bool SNetSendMessage(int dest, void *data, unsigned int size);
virtual bool SNetReceiveTurns(char **data, unsigned int *size, virtual bool SNetReceiveTurns(char **data, unsigned int *size,
DWORD *status); DWORD *status);
virtual bool SNetSendTurn(char *data, unsigned int size); virtual bool SNetSendTurn(char *data, unsigned int size);
virtual int SNetGetProviderCaps(struct _SNETCAPS *caps); virtual int SNetGetProviderCaps(struct _SNETCAPS *caps);
virtual bool SNetRegisterEventHandler(event_type evtype, virtual bool SNetRegisterEventHandler(event_type evtype,
SEVTHANDLER func); SEVTHANDLER func);
virtual bool SNetUnregisterEventHandler(event_type evtype, virtual bool SNetUnregisterEventHandler(event_type evtype,
SEVTHANDLER func); SEVTHANDLER func);
virtual bool SNetLeaveGame(int type); virtual bool SNetLeaveGame(int type);
virtual bool SNetDropPlayer(int playerid, DWORD flags); virtual bool SNetDropPlayer(int playerid, DWORD flags);
virtual bool SNetGetOwnerTurnsWaiting(DWORD *turns); virtual bool SNetGetOwnerTurnsWaiting(DWORD *turns);
@ -46,6 +46,8 @@ public:
void setup_gameinfo(buffer_t info); void setup_gameinfo(buffer_t info);
virtual ~base() = default;
protected: protected:
std::map<event_type, SEVTHANDLER> registered_handlers; std::map<event_type, SEVTHANDLER> registered_handlers;
buffer_t game_init_info; buffer_t game_init_info;
@ -54,13 +56,13 @@ protected:
int sender; // change int to something else in devilution code later int sender; // change int to something else in devilution code later
buffer_t payload; buffer_t payload;
message_t() message_t()
: sender(-1) : sender(-1)
, payload({}) , payload({})
{ {
} }
message_t(int s, buffer_t p) message_t(int s, buffer_t p)
: sender(s) : sender(s)
, payload(p) , payload(p)
{ {
} }
}; };

1
SourceX/dvlnet/cdwrap.cpp

@ -0,0 +1 @@
#include "dvlnet/cdwrap.h"

155
SourceX/dvlnet/cdwrap.h

@ -0,0 +1,155 @@
#pragma once
#include <vector>
#include <memory>
#include <string>
#include <exception>
#include <map>
#include "devilution.h"
#include "dvlnet/abstract_net.h"
namespace dvl {
namespace net {
template <class T>
class cdwrap : public abstract_net {
private:
std::unique_ptr<abstract_net> dvlnet_wrap;
std::map<event_type, SEVTHANDLER> registered_handlers;
buffer_t game_init_info;
void reset();
public:
virtual int create(std::string addrstr, std::string passwd);
virtual int join(std::string addrstr, std::string passwd);
virtual bool SNetReceiveMessage(int *sender, char **data, int *size);
virtual bool SNetSendMessage(int dest, void *data,
unsigned int size);
virtual bool SNetReceiveTurns(char **data, unsigned int *size,
DWORD *status);
virtual bool SNetSendTurn(char *data, unsigned int size);
virtual int SNetGetProviderCaps(struct _SNETCAPS *caps);
virtual bool SNetRegisterEventHandler(event_type evtype,
SEVTHANDLER func);
virtual bool SNetUnregisterEventHandler(event_type evtype,
SEVTHANDLER func);
virtual bool SNetLeaveGame(int type);
virtual bool SNetDropPlayer(int playerid, DWORD flags);
virtual bool SNetGetOwnerTurnsWaiting(DWORD *turns);
virtual bool SNetGetTurnsInTransit(int *turns);
virtual void setup_gameinfo(buffer_t info);
virtual ~cdwrap() = default;
};
template <class T>
void cdwrap<T>::reset()
{
dvlnet_wrap.reset(new T);
dvlnet_wrap->setup_gameinfo(game_init_info);
for (const auto &pair : registered_handlers)
dvlnet_wrap->SNetRegisterEventHandler(pair.first, pair.second);
}
template <class T>
int cdwrap<T>::create(std::string addrstr, std::string passwd)
{
reset();
return dvlnet_wrap->create(addrstr, passwd);
}
template <class T>
int cdwrap<T>::join(std::string addrstr, std::string passwd)
{
reset();
return dvlnet_wrap->join(addrstr, passwd);
}
template <class T>
void cdwrap<T>::setup_gameinfo(buffer_t info)
{
game_init_info = std::move(info);
if (dvlnet_wrap)
dvlnet_wrap->setup_gameinfo(game_init_info);
}
template <class T>
bool cdwrap<T>::SNetReceiveMessage(int *sender, char **data, int *size)
{
return dvlnet_wrap->SNetReceiveMessage(sender, data, size);
}
template <class T>
bool cdwrap<T>::SNetSendMessage(int playerID, void *data, unsigned int size)
{
return dvlnet_wrap->SNetSendMessage(playerID, data, size);
}
template <class T>
bool cdwrap<T>::SNetReceiveTurns(char **data, unsigned int *size, DWORD *status)
{
return dvlnet_wrap->SNetReceiveTurns(data, size, status);
}
template <class T>
bool cdwrap<T>::SNetSendTurn(char *data, unsigned int size)
{
return dvlnet_wrap->SNetSendTurn(data, size);
}
template <class T>
int cdwrap<T>::SNetGetProviderCaps(struct _SNETCAPS *caps)
{
return dvlnet_wrap->SNetGetProviderCaps(caps);
}
template <class T>
bool cdwrap<T>::SNetUnregisterEventHandler(event_type evtype, SEVTHANDLER func)
{
registered_handlers.erase(evtype);
if (dvlnet_wrap)
return dvlnet_wrap->SNetUnregisterEventHandler(evtype, func);
else
return true;
}
template <class T>
bool cdwrap<T>::SNetRegisterEventHandler(event_type evtype, SEVTHANDLER func)
{
registered_handlers[evtype] = func;
if (dvlnet_wrap)
return dvlnet_wrap->SNetRegisterEventHandler(evtype, func);
else
return true;
}
template <class T>
bool cdwrap<T>::SNetLeaveGame(int type)
{
return dvlnet_wrap->SNetLeaveGame(type);
}
template <class T>
bool cdwrap<T>::SNetDropPlayer(int playerid, DWORD flags)
{
return dvlnet_wrap->SNetDropPlayer(playerid, flags);
}
template <class T>
bool cdwrap<T>::SNetGetOwnerTurnsWaiting(DWORD *turns)
{
return dvlnet_wrap->SNetGetOwnerTurnsWaiting(turns);
}
template <class T>
bool cdwrap<T>::SNetGetTurnsInTransit(int *turns)
{
return dvlnet_wrap->SNetGetTurnsInTransit(turns);
}
} // namespace net
} // namespace dvl

24
SourceX/dvlnet/tcp_client.cpp

@ -40,10 +40,10 @@ int tcp_client::join(std::string addrstr, std::string passwd)
start_recv(); start_recv();
{ {
randombytes_buf(reinterpret_cast<unsigned char *>(&cookie_self), randombytes_buf(reinterpret_cast<unsigned char *>(&cookie_self),
sizeof(cookie_t)); sizeof(cookie_t));
auto pkt = pktfty->make_packet<PT_JOIN_REQUEST>(PLR_BROADCAST, auto pkt = pktfty->make_packet<PT_JOIN_REQUEST>(PLR_BROADCAST,
PLR_MASTER, cookie_self, PLR_MASTER, cookie_self,
game_init_info); game_init_info);
send(*pkt); send(*pkt);
for (auto i = 0; i < no_sleep; ++i) { for (auto i = 0; i < no_sleep; ++i) {
try { try {
@ -88,8 +88,8 @@ void tcp_client::handle_recv(const asio::error_code &error, size_t bytes_read)
void tcp_client::start_recv() void tcp_client::start_recv()
{ {
sock.async_receive(asio::buffer(recv_buffer), sock.async_receive(asio::buffer(recv_buffer),
std::bind(&tcp_client::handle_recv, this, std::bind(&tcp_client::handle_recv, this,
std::placeholders::_1, std::placeholders::_2)); std::placeholders::_1, std::placeholders::_2));
} }
void tcp_client::handle_send(const asio::error_code &error, size_t bytes_sent) void tcp_client::handle_send(const asio::error_code &error, size_t bytes_sent)
@ -107,10 +107,16 @@ void tcp_client::send(packet &pkt)
}); });
} }
bool tcp_client::SNetLeaveGame(int type){ bool tcp_client::SNetLeaveGame(int type)
if(sock.is_open()) {
sock.close(); auto ret = base::SNetLeaveGame(type);
return true; poll();
local_server.reset();
return ret;
}
tcp_client::~tcp_client()
{
} }
} // namespace net } // namespace net

5
SourceX/dvlnet/tcp_client.h

@ -19,13 +19,16 @@ class tcp_client : public base {
public: public:
int create(std::string addrstr, std::string passwd); int create(std::string addrstr, std::string passwd);
int join(std::string addrstr, std::string passwd); int join(std::string addrstr, std::string passwd);
virtual bool SNetLeaveGame(int type);
constexpr static unsigned short default_port = 6112; constexpr static unsigned short default_port = 6112;
virtual void poll(); virtual void poll();
virtual void send(packet &pkt); virtual void send(packet &pkt);
virtual bool SNetLeaveGame(int type);
virtual ~tcp_client();
private: private:
frame_queue recv_queue; frame_queue recv_queue;
buffer_t recv_buffer = buffer_t(frame_queue::max_frame_size); buffer_t recv_buffer = buffer_t(frame_queue::max_frame_size);

44
SourceX/dvlnet/tcp_server.cpp

@ -9,9 +9,9 @@ namespace dvl {
namespace net { namespace net {
tcp_server::tcp_server(asio::io_context &ioc, std::string bindaddr, tcp_server::tcp_server(asio::io_context &ioc, std::string bindaddr,
unsigned short port, std::string pw) unsigned short port, std::string pw)
: ioc(ioc) : ioc(ioc)
, pktfty(pw) , pktfty(pw)
{ {
auto addr = asio::ip::address::from_string(bindaddr); auto addr = asio::ip::address::from_string(bindaddr);
auto ep = asio::ip::tcp::endpoint(addr, port); auto ep = asio::ip::tcp::endpoint(addr, port);
@ -57,13 +57,13 @@ bool tcp_server::empty()
void tcp_server::start_recv(scc con) void tcp_server::start_recv(scc con)
{ {
con->socket.async_receive(asio::buffer(con->recv_buffer), con->socket.async_receive(asio::buffer(con->recv_buffer),
std::bind(&tcp_server::handle_recv, this, con, std::bind(&tcp_server::handle_recv, this, con,
std::placeholders::_1, std::placeholders::_1,
std::placeholders::_2)); std::placeholders::_2));
} }
void tcp_server::handle_recv(scc con, const asio::error_code &ec, void tcp_server::handle_recv(scc con, const asio::error_code &ec,
size_t bytes_read) size_t bytes_read)
{ {
if (ec || bytes_read == 0) { if (ec || bytes_read == 0) {
drop_connection(con); drop_connection(con);
@ -92,7 +92,7 @@ void tcp_server::handle_recv(scc con, const asio::error_code &ec,
void tcp_server::send_connect(scc con) void tcp_server::send_connect(scc con)
{ {
auto pkt = pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, auto pkt = pktfty.make_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST,
con->plr); con->plr);
send_packet(*pkt); send_packet(*pkt);
} }
@ -104,8 +104,8 @@ void tcp_server::handle_recv_newplr(scc con, packet &pkt)
if (empty()) if (empty())
game_init_info = pkt.info(); game_init_info = pkt.info();
auto reply = pktfty.make_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST, auto reply = pktfty.make_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST,
pkt.cookie(), newplr, pkt.cookie(), newplr,
game_init_info); game_init_info);
start_send(con, *reply); start_send(con, *reply);
con->plr = newplr; con->plr = newplr;
connections[newplr] = con; connections[newplr] = con;
@ -137,14 +137,14 @@ void tcp_server::start_send(scc con, packet &pkt)
const auto *frame = new buffer_t(frame_queue::make_frame(pkt.data())); const auto *frame = new buffer_t(frame_queue::make_frame(pkt.data()));
auto buf = asio::buffer(*frame); auto buf = asio::buffer(*frame);
asio::async_write(con->socket, buf, asio::async_write(con->socket, buf,
[this, con, frame](const asio::error_code &ec, size_t bytes_sent) { [this, con, frame](const asio::error_code &ec, size_t bytes_sent) {
handle_send(con, ec, bytes_sent); handle_send(con, ec, bytes_sent);
delete frame; delete frame;
}); });
} }
void tcp_server::handle_send(scc con, const asio::error_code &ec, void tcp_server::handle_send(scc con, const asio::error_code &ec,
size_t bytes_sent) size_t bytes_sent)
{ {
// empty for now // empty for now
} }
@ -153,9 +153,9 @@ void tcp_server::start_accept()
{ {
auto nextcon = make_connection(); auto nextcon = make_connection();
acceptor->async_accept(nextcon->socket, acceptor->async_accept(nextcon->socket,
std::bind(&tcp_server::handle_accept, std::bind(&tcp_server::handle_accept,
this, nextcon, this, nextcon,
std::placeholders::_1)); std::placeholders::_1));
} }
void tcp_server::handle_accept(scc con, const asio::error_code &ec) void tcp_server::handle_accept(scc con, const asio::error_code &ec)
@ -176,7 +176,7 @@ void tcp_server::start_timeout(scc con)
{ {
con->timer.expires_after(std::chrono::seconds(1)); con->timer.expires_after(std::chrono::seconds(1));
con->timer.async_wait(std::bind(&tcp_server::handle_timeout, this, con, con->timer.async_wait(std::bind(&tcp_server::handle_timeout, this, con,
std::placeholders::_1)); std::placeholders::_1));
} }
void tcp_server::handle_timeout(scc con, const asio::error_code &ec) void tcp_server::handle_timeout(scc con, const asio::error_code &ec)
@ -200,7 +200,7 @@ void tcp_server::drop_connection(scc con)
{ {
if (con->plr != PLR_BROADCAST) { if (con->plr != PLR_BROADCAST) {
auto pkt = pktfty.make_packet<PT_DISCONNECT>(PLR_MASTER, PLR_BROADCAST, auto pkt = pktfty.make_packet<PT_DISCONNECT>(PLR_MASTER, PLR_BROADCAST,
con->plr, LEAVE_DROP); con->plr, LEAVE_DROP);
connections[con->plr] = nullptr; connections[con->plr] = nullptr;
send_packet(*pkt); send_packet(*pkt);
// TODO: investigate if it is really ok for the server to // TODO: investigate if it is really ok for the server to
@ -210,5 +210,9 @@ void tcp_server::drop_connection(scc con)
con->socket.close(); con->socket.close();
} }
tcp_server::~tcp_server()
{
}
} // namespace net } // namespace net
} // namespace dvl } // namespace dvl

7
SourceX/dvlnet/tcp_server.h

@ -21,8 +21,9 @@ class server_exception : public dvlnet_exception {
class tcp_server { class tcp_server {
public: public:
tcp_server(asio::io_context &ioc, std::string bindaddr, tcp_server(asio::io_context &ioc, std::string bindaddr,
unsigned short port, std::string pw); unsigned short port, std::string pw);
std::string localhost_self(); std::string localhost_self();
virtual ~tcp_server();
private: private:
static constexpr int timeout_connect = 30; static constexpr int timeout_connect = 30;
@ -36,8 +37,8 @@ private:
asio::steady_timer timer; asio::steady_timer timer;
int timeout; int timeout;
client_connection(asio::io_context &ioc) client_connection(asio::io_context &ioc)
: socket(ioc) : socket(ioc)
, timer(ioc) , timer(ioc)
{ {
} }
}; };

Loading…
Cancel
Save