neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
packet_connection.hpp
Go to the documentation of this file.
1// packet_connection.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <stdexcept>
40#include <memory>
41#include <deque>
42#include <array>
43#include <algorithm>
44#include <variant>
45#include <boost/bind.hpp>
46#include <boost/asio.hpp>
47#include <boost/asio/ssl.hpp>
51#include <neolib/io/resolver.hpp> // protocol_family
53
54namespace neolib
55{
56 typedef boost::asio::ip::tcp tcp_protocol;
57 typedef boost::asio::ip::udp udp_protocol;
58
59 template <typename CharType>
61 {
62 // types
63 public:
65 typedef typename packet_type::clone_pointer packet_clone_pointer;
66 // interface
67 public:
70 virtual void handle_connection_failure(const boost::system::error_code& aError) = 0;
71 virtual void handle_packet_sent(const packet_type& aPacket) = 0;
72 virtual void handle_packet_arrived(const packet_type& aPacket) = 0;
73 virtual void handle_transfer_failure(const packet_type& aPacket, const boost::system::error_code& aError) = 0;
74 virtual void handle_connection_closed() = 0;
75 };
76
78
79 template <typename CharType, typename Protocol, size_t ReceiveBufferSize = 1024>
81 {
82 // types
83 public:
84 typedef Protocol protocol_type;
85 private:
88 typedef i_basic_packet<CharType> packet_type;
89 typedef const packet_type* const_packet_pointer;
90 typedef std::deque<const_packet_pointer> send_queue;
91 typedef typename protocol_type::socket socket_type;
92 typedef std::shared_ptr<socket_type> socket_pointer;
93 typedef boost::asio::ssl::stream<tcp_protocol::socket> secure_stream_type;
94 typedef std::shared_ptr<secure_stream_type> secure_stream_pointer;
95 typedef std::variant<std::monostate, socket_pointer, secure_stream_pointer> socket_holder_type;
96 typedef boost::asio::ssl::context secure_stream_context;
97 typedef std::unique_ptr<secure_stream_context> secure_stream_context_pointer;
98 typedef typename protocol_type::endpoint endpoint_type;
99 typedef typename protocol_type::resolver resolver_type;
100 typedef std::array<char, ReceiveBufferSize * sizeof(CharType)> receive_buffer;
101 typedef boost::asio::ssl::context secure_context;
102 class handler_proxy
103 {
104 public:
105 handler_proxy(our_type& aParent) : iParentDestroyed{ aParent }, iParent{ aParent }, iOrphaned{ false }
106 {
107 }
108 public:
109 void handle_resolve(const boost::system::error_code& aError, typename resolver_type::iterator aEndPointIterator)
110 {
111 if (!iParentDestroyed && !iOrphaned)
112 iParent.handle_resolve(aError, aEndPointIterator);
113 }
114 void handle_connect(const boost::system::error_code& aError)
115 {
116 if (!iParentDestroyed && !iOrphaned)
117 iParent.handle_connect(aError);
118 }
119 void handle_handshake(const boost::system::error_code& aError)
120 {
121 if (!iParentDestroyed && !iOrphaned)
122 iParent.handle_handshake(aError);
123 }
124 void handle_write(const boost::system::error_code& aError, size_t aBytesTransferred)
125 {
126 if (!iParentDestroyed && !iOrphaned)
127 iParent.handle_write(aError, aBytesTransferred);
128 }
129 void handle_read(const boost::system::error_code& aError, size_t aBytesTransferred)
130 {
131 if (!iParentDestroyed && !iOrphaned)
132 iParent.handle_read(aError, aBytesTransferred);
133 }
134 void orphan(bool aCreateNewHandlerProxy = true)
135 {
136 iOrphaned = true;
137 if (aCreateNewHandlerProxy)
138 iParent.iHandlerProxy = std::make_shared<handler_proxy>(iParent);
139 else
140 iParent.iHandlerProxy.reset();
141 }
142 private:
143 destroyed_flag iParentDestroyed;
144 our_type& iParent;
145 bool iOrphaned;
146 };
147
148 // exceptions
149 public:
150 struct already_open : std::logic_error { already_open() : std::logic_error("neolib::packet_connection::already_open") {} };
151 struct no_socket : std::logic_error { no_socket() : std::logic_error("neolib::packet_connection::no_socket") {} };
152
153 // construction
154 public:
156 i_async_task& aIoTask,
157 owner_type& aOwner,
158 bool aSecure = false,
159 protocol_family aProtocolFamily = IPv4) :
160 iIoTask(aIoTask),
161 iOwner(aOwner),
162 iHandlerProxy(new handler_proxy(*this)),
163 iLocalHostName(),
164 iLocalPort(0),
165 iRemoteHostName(),
166 iRemotePort(0),
167 iSecure(aSecure),
168 iProtocolFamily(aProtocolFamily),
169 iError(false),
170 iResolver(aIoTask.io_service().native_object<boost::asio::io_service>()),
171 iConnected(false),
172 iPacketBeingSent(nullptr),
173 iReceiveBufferPtr(&iReceiveBuffer[0]),
174 iReceivePacket(aOwner.handle_create_empty_packet())
175 {
176 }
178 i_async_task& aIoTask,
179 owner_type& aOwner,
180 const std::string& aRemoteHostName,
181 unsigned short aRemotePort,
182 bool aSecure = false,
183 protocol_family aProtocolFamily = IPv4) :
184 iIoTask(aIoTask),
185 iOwner(aOwner),
186 iHandlerProxy(new handler_proxy(*this)),
187 iLocalHostName(),
188 iLocalPort(0),
189 iRemoteHostName(aRemoteHostName),
190 iRemotePort(aRemotePort),
191 iSecure(aSecure),
192 iProtocolFamily(aProtocolFamily),
193 iError(false),
194 iResolver(aIoTask.io_service().native_object<boost::asio::io_service>()),
195 iConnected(false),
196 iPacketBeingSent(nullptr),
197 iReceiveBufferPtr(&iReceiveBuffer[0]),
198 iReceivePacket(aOwner.handle_create_empty_packet())
199 {
200 open();
201 }
203 {
205 close();
206 }
207
208 // operations
209 public:
210 bool open(const std::string& aRemoteHostName, unsigned short aRemotePort, bool aSecure = false, protocol_family aProtocolFamily = IPv4)
211 {
212 if (opened())
213 throw already_open();
214 iLocalHostName = std::string();
215 iLocalPort = 0;
216 iRemoteHostName = aRemoteHostName;
217 iRemotePort = aRemotePort;
218 iSecure = aSecure;
219 iProtocolFamily = aProtocolFamily;
220 iError = false;
221 return open();
222 }
223 bool open(bool aAcceptingSocket = false)
224 {
225 if (opened())
226 throw already_open();
227 if (!secure())
228 {
229 iSocketHolder = socket_pointer(new socket_type(iIoTask.io_service().native_object<boost::asio::io_service>()));
230 }
231 else
232 {
233 if (iSecureStreamContext == nullptr)
234 iSecureStreamContext.reset(new secure_stream_context(boost::asio::ssl::context::sslv23));
235 iSocketHolder = secure_stream_pointer(new secure_stream_type(iIoTask.io_service().native_object<boost::asio::io_service>(), *iSecureStreamContext));
236 }
237 if (aAcceptingSocket)
238 return true;
239 boost::system::error_code ec;
240 socket().open(to_protocol<protocol_type>(iProtocolFamily), ec);
241 if (!ec && bind())
242 {
243 resolve();
244 return true;
245 }
246 return false;
247 }
248 void close()
249 {
250 iHandlerProxy->orphan();
251 iResolver.cancel();
252 if (!std::holds_alternative<std::monostate>(iSocketHolder))
253 socket().close();
254 iSocketHolder = none;
255 bool wasConnected = iConnected;
256 iConnected = false;
257 iReceiveBufferPtr = &iReceiveBuffer[0];
258 if (wasConnected)
259 iOwner.handle_connection_closed();
260 }
261 void send_packet(const packet_type& aPacket, bool aHighPriority = false)
262 {
263 iSendQueue.insert(aHighPriority ? iSendQueue.begin() : iSendQueue.end(), &aPacket);
264 send_any();
265 }
266 bool opened() const
267 {
268 if (!secure())
269 {
270 return std::holds_alternative<socket_pointer>(iSocketHolder) && std::get<socket_pointer>(iSocketHolder) != nullptr;
271 }
272 else
273 {
274 return std::holds_alternative<secure_stream_pointer>(iSocketHolder) && std::get<secure_stream_pointer>(iSocketHolder) != nullptr;
275 }
276 }
277 bool closed() const
278 {
279 return !opened();
280 }
281 bool connected() const
282 {
283 return iConnected;
284 }
285 unsigned short local_port() const
286 {
287 return iLocalPort;
288 }
289 unsigned short remote_port() const
290 {
291 return iRemotePort;
292 }
293 bool secure() const
294 {
295 return iSecure;
296 }
297 bool has_error() const
298 {
299 return iError;
300 }
301 const boost::system::error_code& error() const
302 {
303 return iErrorCode;
304 }
305 const endpoint_type& local_end_point() const
306 {
307 return iLocalEndPoint;
308 }
309 const endpoint_type& remote_end_point() const
310 {
311 return iRemoteEndPoint;
312 }
313 template <typename CharType2, size_t ReceiveBufferSize2>
314 friend const typename basic_packet_connection<CharType2, Protocol, ReceiveBufferSize2>::socket_type& do_socket(const basic_packet_connection<CharType2, Protocol, ReceiveBufferSize2>&);
315 const socket_type& socket() const
316 {
317 return do_socket(*this);
318 }
319 template <typename CharType2, size_t ReceiveBufferSize2>
320 friend typename basic_packet_connection<CharType2, Protocol, ReceiveBufferSize2>::socket_type& do_socket(basic_packet_connection<CharType2, Protocol, ReceiveBufferSize2>&);
321 socket_type& socket()
322 {
323 return do_socket(*this);
324 }
325 const secure_stream_type& secure_stream() const
326 {
327 if (closed())
328 throw no_socket();
329 return *std::get<secure_stream_pointer>(iSocketHolder);
330 }
331 secure_stream_type& secure_stream()
332 {
333 if (closed())
334 throw no_socket();
335 return *std::get<secure_stream_pointer>(iSocketHolder);
336 }
338 {
339 iConnected = true;
340 iLocalHostName = socket().local_endpoint().address().to_string();
341 iLocalPort = socket().local_endpoint().port();
342 send_any();
343 receive_any();
344 }
345
346 // implementation
347 private:
348 bool bind()
349 {
350 boost::system::error_code ec;
351 if (iLocalHostName.empty())
352 socket().bind(endpoint_type(to_protocol<protocol_type>(iProtocolFamily), iLocalPort), ec);
353 else
354 {
355 typename resolver_type::iterator result = iResolver.resolve(typename resolver_type::query(iLocalHostName, uint32_to_string<char>(iLocalPort)), ec);
356 if (!ec)
357 {
358 bool foundGoodMatch = false;
359 for (typename resolver_type::iterator i = result; !foundGoodMatch && i != typename resolver_type::iterator(); ++i)
360 {
361 endpoint_type endpoint = *i;
362 if (to_protocol_family(endpoint.protocol()) & iProtocolFamily)
363 {
364 iLocalEndPoint = endpoint;
365 socket().bind(iLocalEndPoint, ec);
366 foundGoodMatch = true;
367 }
368 }
369 if (!foundGoodMatch)
370 {
371 iLocalEndPoint = *result;
372 socket().bind(iLocalEndPoint, ec);
373 }
374 }
375 }
376 if (!ec)
377 {
378 iLocalEndPoint = socket().local_endpoint();
379 iLocalHostName = socket().local_endpoint().address().to_string();
380 iLocalPort = socket().local_endpoint().port();
381 return true;
382 }
383 else
384 {
385 iError = true;
386 iErrorCode = ec;
387 iOwner.handle_connection_failure(ec);
388 return false;
389 }
390 }
391 void resolve()
392 {
393 if (!iRemoteHostName.empty())
394 {
395 iResolver.async_resolve(typename resolver_type::query(iRemoteHostName, uint32_to_string<char>(iRemotePort)),
396 boost::bind(&handler_proxy::handle_resolve, iHandlerProxy, boost::asio::placeholders::error, boost::asio::placeholders::iterator));
397 }
398 }
399
400 // implementation
401 private:
402 void handle_resolve(const boost::system::error_code& aError, typename resolver_type::iterator aEndPointIterator)
403 {
404 if (closed())
405 return;
406 if (!aError)
407 {
408 bool foundGoodMatch = false;
409 for (typename resolver_type::iterator i = aEndPointIterator; !foundGoodMatch && i != typename resolver_type::iterator(); ++i)
410 {
411 endpoint_type endpoint = *i;
412 if (to_protocol_family(endpoint.protocol()) & iProtocolFamily)
413 {
414 foundGoodMatch = true;
415 iRemoteEndPoint = endpoint;
416 socket().async_connect(iRemoteEndPoint, boost::bind(&handler_proxy::handle_connect, iHandlerProxy, boost::asio::placeholders::error));
417 }
418 }
419 if (!foundGoodMatch)
420 {
421 iRemoteEndPoint = *aEndPointIterator;
422 socket().async_connect(iRemoteEndPoint, boost::bind(&handler_proxy::handle_connect, iHandlerProxy, boost::asio::placeholders::error));
423 }
424 }
425 else
426 {
427 iError = true;
428 iErrorCode = aError;
429 iOwner.handle_connection_failure(aError);
430 }
431 }
432 void handle_connect(const boost::system::error_code& aError)
433 {
434 if (closed())
435 return;
436 if (!aError)
437 {
438 iConnected = true;
439 if (!secure())
440 {
441 destroyed_flag destroyed{ *this };
442 iOwner.handle_connection_established();
443 if (destroyed)
444 return;
445 send_any();
446 receive_any();
447 }
448 else
449 {
450 std::get<secure_stream_pointer>(iSocketHolder)->async_handshake(
451 boost::asio::ssl::stream_base::client,
452 boost::bind(&handler_proxy::handle_handshake, iHandlerProxy, boost::asio::placeholders::error));
453 }
454 }
455 else
456 {
457 iError = true;
458 iErrorCode = aError;
459 iOwner.handle_connection_failure(aError);
460 }
461 }
462 void handle_handshake(const boost::system::error_code& aError)
463 {
464 if (closed())
465 return;
466 if (!aError)
467 {
468 destroyed_flag destroyed{ *this };
469 iOwner.handle_connection_established();
470 if (destroyed)
471 return;
472 send_any();
473 receive_any();
474 }
475 else
476 {
477 iError = true;
478 iErrorCode = aError;
479 iOwner.handle_connection_failure(aError);
480 }
481 }
482 void send_any()
483 {
484 if (!connected())
485 return;
486 if (iSendQueue.empty())
487 return;
488 if (iPacketBeingSent != nullptr)
489 return;
490 iPacketBeingSent = iSendQueue.front();
491 iSendQueue.pop_front();
492 if (!secure())
493 {
494 boost::asio::async_write(
495 socket(),
496 boost::asio::buffer(iPacketBeingSent->data(), iPacketBeingSent->length()),
497 boost::bind(
498 &handler_proxy::handle_write,
499 iHandlerProxy,
500 boost::asio::placeholders::error,
501 boost::asio::placeholders::bytes_transferred));
502 }
503 else
504 {
505 boost::asio::async_write(
506 secure_stream(),
507 boost::asio::buffer(iPacketBeingSent->data(), iPacketBeingSent->length()),
508 boost::bind(
509 &handler_proxy::handle_write,
510 iHandlerProxy,
511 boost::asio::placeholders::error,
512 boost::asio::placeholders::bytes_transferred));
513 }
514 }
515 void receive_any()
516 {
517 if (!connected())
518 return;
519
520 if (!secure())
521 {
522 socket().async_read_some(
523 boost::asio::buffer(iReceiveBufferPtr, iReceiveBuffer.size() - (iReceiveBufferPtr - &iReceiveBuffer[0])),
524 boost::bind(
525 &handler_proxy::handle_read,
526 iHandlerProxy,
527 boost::asio::placeholders::error,
528 boost::asio::placeholders::bytes_transferred));
529 }
530 else
531 {
532 secure_stream().async_read_some(
533 boost::asio::buffer(iReceiveBufferPtr, iReceiveBuffer.size() - (iReceiveBufferPtr - &iReceiveBuffer[0])),
534 boost::bind(
535 &handler_proxy::handle_read,
536 iHandlerProxy,
537 boost::asio::placeholders::error,
538 boost::asio::placeholders::bytes_transferred));
539 }
540 }
541 void handle_write(const boost::system::error_code& aError, size_t)
542 {
543 destroyed_flag destroyed{ *this };
544 if (closed())
545 return;
546 const_packet_pointer sentPacket = iPacketBeingSent;
547 iPacketBeingSent = nullptr;
548 if (!aError)
549 {
550 iOwner.handle_packet_sent(*sentPacket);
551 if (destroyed)
552 return;
553 send_any();
554 }
555 else
556 {
557 iError = true;
558 iErrorCode = aError;
559 iOwner.handle_transfer_failure(*sentPacket, aError);
560 if (destroyed)
561 return;
562 close();
563 }
564 }
565 void handle_read(const boost::system::error_code& aError, size_t aBytesTransferred)
566 {
567 destroyed_flag destroyed{ *this };
568 if (closed())
569 return;
570 if (!aError)
571 {
572 typename packet_type::const_pointer start = reinterpret_cast<typename packet_type::pointer>(&iReceiveBuffer[0]);
573 typename packet_type::const_pointer end = start + aBytesTransferred / sizeof(CharType);
574 while(iReceivePacket->take_some(start, end))
575 {
576 if (!iReceivePacket->empty())
577 {
578 iOwner.handle_packet_arrived(*iReceivePacket);
579 if (destroyed)
580 return;
581 iReceivePacket->clear();
582 }
583 }
584 iReceiveBufferPtr = std::copy(
585 reinterpret_cast<typename receive_buffer::const_pointer>(start),
586 reinterpret_cast<typename receive_buffer::const_pointer>(iReceiveBufferPtr + aBytesTransferred),
587 &iReceiveBuffer[0]);
588 receive_any();
589 }
590 else
591 {
592 if (aError.value() != boost::asio::error::eof && opened())
593 {
594 iError = true;
595 iErrorCode = aError;
596 iReceivePacket->clear();
597 iOwner.handle_transfer_failure(*iReceivePacket, aError);
598 if (destroyed)
599 return;
600 }
601 close();
602 }
603 }
604
605 // attibutes
606 private:
607 i_async_task& iIoTask;
608 owner_type& iOwner;
609 std::shared_ptr<handler_proxy> iHandlerProxy;
610 std::string iLocalHostName;
611 unsigned short iLocalPort;
612 std::string iRemoteHostName;
613 unsigned short iRemotePort;
614 bool iSecure;
615 protocol_family iProtocolFamily;
616 bool iError;
617 boost::system::error_code iErrorCode;
618 resolver_type iResolver;
619 endpoint_type iLocalEndPoint;
620 endpoint_type iRemoteEndPoint;
621 secure_stream_context_pointer iSecureStreamContext;
622 socket_holder_type iSocketHolder;
623 bool iConnected;
624 send_queue iSendQueue;
625 const_packet_pointer iPacketBeingSent;
626 receive_buffer iReceiveBuffer;
627 typename receive_buffer::pointer iReceiveBufferPtr;
628 typename packet_type::clone_pointer iReceivePacket;
629 };
630
631 template <typename CharType, size_t ReceiveBufferSize>
632 inline const typename basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>::socket_type& do_socket(const basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>& aConnection)
633 {
635 if (aConnection.closed())
636 throw typename connection_type::no_socket();
637 if (!aConnection.secure())
638 {
639 return *std::get<typename connection_type::socket_pointer>(aConnection.iSocketHolder);
640 }
641 else
642 {
643 return static_cast<const typename connection_type::socket_type&>(std::get<typename connection_type::secure_stream_pointer>(aConnection.iSocketHolder)->lowest_layer());
644 }
645 }
646
647 template <typename CharType, size_t ReceiveBufferSize>
648 inline typename basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>::socket_type& do_socket(basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>& aConnection)
649 {
650 return const_cast<typename basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>::socket_type&>(do_socket(const_cast<const basic_packet_connection<CharType, tcp_protocol, ReceiveBufferSize>&>(aConnection)));
651 }
652
653 template <typename CharType, size_t ReceiveBufferSize>
654 inline const typename basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>::socket_type& do_socket(const basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>& aConnection)
655 {
657 if (aConnection.closed())
658 throw typename connection_type::no_socket();
659 return *std::get<typename connection_type::socket_pointer>(aConnection.iSocketHolder);
660 }
661
662 template <typename CharType, size_t ReceiveBufferSize>
663 inline typename basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>::socket_type& do_socket(basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>& aConnection)
664 {
665 return const_cast<typename basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>::socket_type&>(do_socket(const_cast<const basic_packet_connection<CharType, udp_protocol, ReceiveBufferSize>&>(aConnection)));
666 }
667}
void send_packet(const packet_type &aPacket, bool aHighPriority=false)
const secure_stream_type & secure_stream() const
const endpoint_type & remote_end_point() const
bool open(bool aAcceptingSocket=false)
friend const basic_packet_connection< CharType2, Protocol, ReceiveBufferSize2 >::socket_type & do_socket(const basic_packet_connection< CharType2, Protocol, ReceiveBufferSize2 > &)
const socket_type & socket() const
bool open(const std::string &aRemoteHostName, unsigned short aRemotePort, bool aSecure=false, protocol_family aProtocolFamily=IPv4)
basic_packet_connection(i_async_task &aIoTask, owner_type &aOwner, bool aSecure=false, protocol_family aProtocolFamily=IPv4)
friend basic_packet_connection< CharType2, Protocol, ReceiveBufferSize2 >::socket_type & do_socket(basic_packet_connection< CharType2, Protocol, ReceiveBufferSize2 > &)
basic_packet_connection(i_async_task &aIoTask, owner_type &aOwner, const std::string &aRemoteHostName, unsigned short aRemotePort, bool aSecure=false, protocol_family aProtocolFamily=IPv4)
const endpoint_type & local_end_point() const
const boost::system::error_code & error() const
virtual void * native_object()=0
virtual i_async_service & io_service()=0
virtual void handle_packet_sent(const packet_type &aPacket)=0
virtual packet_clone_pointer handle_create_empty_packet() const =0
virtual void handle_connection_failure(const boost::system::error_code &aError)=0
virtual void handle_transfer_failure(const packet_type &aPacket, const boost::system::error_code &aError)=0
virtual void handle_packet_arrived(const packet_type &aPacket)=0
packet_type::clone_pointer packet_clone_pointer
void set_destroying() override
Definition lifetime.hpp:165
neolib::destroyed_flag destroyed_flag
Definition lifetime.hpp:87
boost::asio::ip::tcp tcp_protocol
i_basic_packet_connection_owner< char > packet_connection_owner
protocol_family to_protocol_family(Protocol aProtocol)
Definition resolver.hpp:59
boost::asio::ip::udp udp_protocol
auto destroyed(Object &aObject, const Handler aHandler)
Definition i_object.hpp:73
protocol_family
Definition resolver.hpp:52
const basic_packet_connection< CharType, tcp_protocol, ReceiveBufferSize >::socket_type & do_socket(const basic_packet_connection< CharType, tcp_protocol, ReceiveBufferSize > &aConnection)
const none_t none
Definition variant.hpp:111