Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

Prev

ip::tcp::socket

The TCP socket type.

Member Functions

Data members, protected data members.

The basic_stream_socket class template provides asynchronous and blocking stream-oriented socket functionality.

Thread Safety

Distinct objects: Safe.

Shared objects: Unsafe.

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

Prev

ip::udp::socket

The UDP socket type.

Member Functions

Protected member functions, data members, protected data members.

The basic_datagram_socket class template provides asynchronous and blocking datagram-oriented socket functionality.

Thread Safety

Distinct objects: Safe.

Shared objects: Unsafe.

Requirements

Header: boost/asio/ip/udp.hpp

Convenience header: boost/asio.hpp

C++ – How to set a timeout on blocking sockets in boost asio

boost boost-asio c sockets

Is there a way to cancel a pending operation (without disconnect) or set a timeout for the boost library functions?

I.e. I want to set a timeout on blocking socket in boost asio?

socket.read_some(boost::asio::buffer(pData, maxSize), error_);

Example: I want to read some from the socket, but I want to throw an error if 10 seconds have passed.

Best Answer

FULL ANSWER This question keep being asked over and over again for many years. Answers I saw so far are quite poor. I'll add this info right here in one of the first occurrences of this question.

Everybody trying to use ASIO to simplify their networking code would be perfectly happy if the author would just add an optional parameter timeout to all sync and async io functions. Unfortunately, this is unlikely to happen (in my humble opinion, just for ideological reasons, after all, AS in ASIO is for a reason).

So these are the ways to skin this poor cat available so far, none of them especially appetizing. Let's say we need 200ms timeout.

1) Good (bad) old socket API:

Please note those peculiarities: - const int for timeout - on Windows the required type is actually DWORD, but the current set of compilers luckily has it the same, so const int will work both in Win and Posix world. - (const char*) for value. On Windows const char* is required, Posix requires const void*, in C++ const char* will convert to const void* silently while the opposite is not true.

Advantages: works and probably will always work as the socket API is old and stable. Simple enough. Fast. Disadvantages: technically might require appropriate header files (different on Win and even different UNIX flavors) for setsockopt and the macros, but current implementation of ASIO pollutes global namespace with them anyway. Requires a variable for timeout. Not type-safe. On Windows, requires that the socket is in overlapped mode to work (which current ASIO implementation luckily uses, but it is still an implementation detail). UGLY!

2) Custom ASIO socket option:

Advantages: Simple enough. Fast. Beautiful (with typedef). Disadvantages: Depends on ASIO implementation detail, which might change (but OTOH everything will change eventually, and such detail is less likely to change then public APIs subject to standardization). But in case this happens, you'll have to either write a class according to https://www.boost.org/doc/libs/1_68_0/doc/html/boost_asio/reference/SettableSocketOption.html (which is of course a major PITA thanks to obvious overengineering of this part of ASIO) or better yet revert to 1.

3) Use C++ async/future facilities.

Advantages: standard. Disadvantages: always starts a new thread (in practice), which is relatively slow (might be good enough for clients, but will lead to DoS vulnerability for servers as threads and sockets are "expensive" resources). Don't try to use std::launch::deferred instead of std::launch::async to avoid new thread launch as wait_for will always return future_status::deferred without trying to run the code.

4) The method prescribed by ASIO - use async operations only (which is not really the answer to the question).

Advantages: good enough for servers too if huge scalability for short transactions is not required. Disadvantages: quite wordy (so I will not even include examples - see ASIO examples). Requires very careful lifetime management of all your objects used both by async operations and their completion handlers, which in practice requires all classes containing and using such data in async operations be derived from enable_shared_from_this, which requires all such classes allocated on heap, which means (at least for short operations) that scalability will start taper down after about 16 threads as every heap alloc/dealloc will use a memory barrier.

Related Solutions

C++ – how to set, clear, and toggle a single bit, setting a bit.

Use the bitwise OR operator ( | ) to set a bit.

That will set the n th bit of number . n should be zero, if you want to set the 1 st bit and so on upto n-1 , if you want to set the n th bit.

Use 1ULL if number is wider than unsigned long ; promotion of 1UL << n doesn't happen until after evaluating 1UL << n where it's undefined behaviour to shift by more than the width of a long . The same applies to all the rest of the examples.

Clearing a bit

Use the bitwise AND operator ( & ) to clear a bit.

That will clear the n th bit of number . You must invert the bit string with the bitwise NOT operator ( ~ ), then AND it.

Toggling a bit

The XOR operator ( ^ ) can be used to toggle a bit.

That will toggle the n th bit of number .

Checking a bit

You didn't ask for this, but I might as well add it.

To check a bit, shift the number n to the right, then bitwise AND it:

That will put the value of the n th bit of number into the variable bit .

Changing the n th bit to x

Setting the n th bit to either 1 or 0 can be achieved with the following on a 2's complement C++ implementation:

Bit n will be set if x is 1 , and cleared if x is 0 . If x has some other value, you get garbage. x = !!x will booleanize it to 0 or 1.

To make this independent of 2's complement negation behaviour (where -1 has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.

It's generally a good idea to use unsigned types for portable bit manipulation.

(number & ~(1UL << n)) will clear the n th bit and (x << n) will set the n th bit to x .

It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down ) or some sort of encapsulation.

C++ – boost::asio cleanly disconnecting

I think you should probably have a call to socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec) in there before the call to socket.close() .

The boost::asio documentation for basic_stream_socket::close states:

For portable behaviour with respect to graceful closure of a connected socket, call shutdown() before closing the socket.

This should ensure that any pending operations on the socket are properly cancelled and any buffers are flushed prior to the call to socket.close.

Related Topic

  • C++ – boost asio,how to cancel an asynchronous operation
  • C++ – How does libuv compare to Boost/ASIO

boost socket set_option timeout

  • Latest Articles
  • Top Articles
  • Posting/Update Guidelines
  • Article Help Forum

boost socket set_option timeout

  • View Unanswered Questions
  • View All Questions
  • View C# questions
  • View C++ questions
  • View Javascript questions
  • View Visual Basic questions
  • View Python questions
  • CodeProject.AI Server
  • All Message Boards...
  • Running a Business
  • Sales / Marketing
  • Collaboration / Beta Testing
  • Work Issues
  • Design and Architecture
  • Artificial Intelligence
  • Internet of Things
  • ATL / WTL / STL
  • Managed C++/CLI
  • Objective-C and Swift
  • System Admin
  • Hosting and Servers
  • Linux Programming
  • .NET (Core and Framework)
  • Visual Basic
  • Web Development
  • Site Bugs / Suggestions
  • Spam and Abuse Watch
  • Competitions
  • The Insider Newsletter
  • The Daily Build Newsletter
  • Newsletter archive
  • CodeProject Stuff
  • Most Valuable Professionals
  • The Lounge  
  • The CodeProject Blog
  • Where I Am: Member Photos
  • The Insider News
  • The Weird & The Wonderful
  • What is 'CodeProject'?
  • General FAQ
  • Ask a Question
  • Bugs and Suggestions

boost socket set_option timeout

Socket Programming in C++ using boost.asio: TCP Server and Client

boost socket set_option timeout

  • Download source code - 2.1 KB

Introduction

Socket programming is nothing of a new concept for programmers. Ever since the internet came into existence, it shifted the paradigm to internet-enabled applications. That’s where network programming models starts to appear. A socket is fundamentally the most basic technology of this network programming. Let alone the technology for the moment, in most cases, it’s literally just a client-server model working. Server is supposed to serve the information requested or the required services by the client . The following analogy will help you understand the model.

Image 1

But how does that transfer of information take place? Well, that involves networking services from transport layer often referred to as TCP/IP (Transport Control Protocol/Internet Protocol). For example, when you open your browser and search for something, you’re merely requesting a server for some information over HTTP (not to forget HTTP is nothing but an application using TCP/IP service). But where are the sockets? Let me refer you back to the line where I said sockets are the “base” and so they provide the programming interface for these protocols to work on. Generally speaking, sockets are providing a way for two processes or programs to communicate over the network . Sockets provide sufficiency and transparency while causing almost no communication overhead.

Image 2

Why C++ though? As I mentioned earlier, sockets are merely providing an interface for network programming and have nothing to do with programming language used for implementation. C++ might be the best choice in this regard because of the speed and efficiency it brings to the table. Some might not agree with me at this statement because of implied complexity by the language including but not restricted to manual memory management, template syntax, library incompatibility, compiler, etc. But I think differently. C++ will let you dig deep and see the insights of what actually is going on at the lower level although good concept and knowledge in computer networks is not debatable. This article will help you in giving a soft start with socket programming in C++ using boost library. But before digging into the code, let’s clarify a few points a bit more.

What Socket Programming is All About?

Let’s talk about what a socket actually is and how it plays its role in the communication.

Socket is merely one endpoint of a two-way communication link. It represents a single connection between two entities that are trying to communicate over the network most of the time which are server and client. More than two entities can also be set to communicate but by using multiple sockets.

This socket-based communication is done over the network; one end of which could be your computer while other could be at the other end of the world (considering again the browsing example) or over the same machine (local host). Now the question arises how the server knows that a client is requesting for connection and also which service is being requested? This all is the game of IP address and port number . Every computer has a specific IP address which will be used to identify it. (If you’re accessing a website, then the name will eventually be translated into IP address.) Which service, is distinguished by port number.

Now to sum it all up when a client is requesting a server for services, it opens a socket and passes the request to the server by specifying its IP address and port number (to let server know which service is meant to be provided.) The server will accept the connection request and transfer the data or provide any other service requested. Once request is served, the connection will be closed. Observe the workflow in the following diagram.

Why Boost.Asio?

Writing networking code that is portable is easy to maintain has been an issue since long. C++ took a step to resolve this issue by introducing boost.asio . It is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach. Here’s a list of what it offers:

  • Cross platform networking code (code would work on Windows, Linux, etc.)
  • IPv4 and IPv6 support
  • Asynchronous event support
  • Timer support
  • iostream compatibility

And much more. You can get the complete overview of the library here .

We are not going to dig deep into networking but rather will develop a simple client-server model and see how things work. So without any further delay, let’s get started.

Environment Setup

I’m currently in Linux (18.04 LTS) so would be covering environment setup for the same.

We just need the following to get started:

  • C++ compiler (preferably g++)
  • Text-editor

The simplest way to get asio on linux is by executing the following command:

If you’re using some other platform or the above doesn’t seem a good fit for you, follow the document here to get asio on your system.

The next step is to make sure you have C++ compiler on your compiler. I’m using g++. You can get the same with the following command in linux.

Once you have the compiler, you’re good to follow along. I don’t have any text-editor preference. You can choose one of your choice.

Now that we have everything, we are in a position to start coding for our TCP server-client model.

As we mentioned earlier in the article, the server specifies an address for client at which it makes a request to server. Server listens for the new connection and responds accordingly. Now here are the steps for our server development.

Of course, we need to import our libraries before anything else. So here we go:

using namespace std is considered a bad practice for the reason that it imports all sorts of names globally and can cause ambiguities. As we just need three names that belong to std namespace, it's better to import them separately or else suit yourself.

We want our server to receive a message from client and then respond back. For that, we need two functions for read and write.

Let’s break things down a little bit. Here, we are using tcp socket for communication. read_until and write functions from boost::asio has been used to perform the desired function. boost::asio::buffer creates a buffer of the data that is being communicated.

Now that we have our functions, let’s kick the server in.

io_service object is needed whenever a program is using asio. tcp::acceptor is used to listen for connection requested by the client. We are passing two arguments to the function; one is the same io_service object we declared previously and next is the end point of connection being initialised to ipv4 and port 1234 . Next server will create a socket and wait for connection from client. As soon as the connection is built, our read and write operations will be executed and connection will be closed.

We need the other end for our communication as well, i.e., a client that requests server. The basic structure is the same as we did for server.

Those are the same imports as we did for server. Nothing new.

We again started by creating the io_service object and creating the socket. We need to connect to server using localhost (IP 127.0.0.1) and specifying the same port as we did for server to establish the connection successfully. Once the connection is established, we’re sending a hello message to server using boost::asio::write . If the message is transferred, then server will send back the respond. For this purpose, we have boost::asio::read function to read back the response. Now let‘s run our program to see things in action.

Compile and run the server by executing the following command:

Move to the other terminal window to run client.

Image 4

Observe the workflow from the above output. The client sent its request by saying hello to the server after which the server responded back with hello. Once the data transfer is complete, connection is closed.

TCP Asynchronous Server

The above programs explain our simple synchronous TCP server and client in which we did the operations in sequential order, i.e., reading from socket then write. Each operation is blocking which means read operation should finish first and then we can do the write operation. But what if there is more than one client trying to connect to server? In case we don’t want our main program to be interrupted while we're reading from or writing to a socket, a multi-threaded TCP client-server is required to handle the situation. The other option is having an asynchronous server. We can start the operation, but we don’t know when it will end, we don’t need to know pre-hand either because it is not blocking. The other operations can be performed side by side. Think of synchronous as walkie-talkie where one can speak at a time whereas asynchronous is more like regular cellphone. Now that we know the basics, let‘s dive in and try to create an asynchronous server.

We have two new imports, bind and enable_shared_from_this . We’ll be using the former to bind any argument to a specific value and route input arguments into arbitrary positions. The latter is to get a valid shared_ptr instance.

Let’s define a class to handle the connection as follows:

The shared_ptr and enabled_shared_from_this is to keep our object alive for any operation that refers to it. Then we created the socket pretty much the same way as we did in case of synchronous server. Now is the time to specify the functions we want to perform using that socket. We are using async_read_some and async_write_some functions to achieve the same functionality as that of our previously developed server but now asynchronously. boost::bind is being used to bind and route the arguments to handle_read/write . handle_read/write will now be responsible for any further action. If you look into the handle_read / write definition, it has the same arguments as the last two of boot::bind and is performing some action in case the data is successfully transferred between client and server or not.

Our server class will create a socket and will start the accept operation to wait for connection asynchronously. We also defined a constructor for our server to start listening for connection on the specified port. If no error occurs, connection with the client will be established. Here’s our main function.

Again, we need our io_service object along with an instance of Server class. run() function will block until all the work is done, until io_service is stopped.

It’s time to let our monster out. Compile and run the above code with:

Run your client again.

Image 6

Note that the client closed the connection after exchanging the data but server is still up and running. New connections can be made to the server or else it will continue to run until explicitly asked to stop. If we want it to stop, then we can do the following:

This will tell run() that all work is done and not to block anymore.

This article is not meant to show you the best practices or making you a pro in network programming rather focused to give you an easy start with socket programming in boost.asio . It is a pretty handy library so if you’re interested in some high-end network programming, I would encourage you to take a deep dive and play around it more. Also, the source code of both server and client is attached. Feel free to make some changes and let me know if you have some good ideas.

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Twitter

Comments and Discussions

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

boost socket set_option timeout

Search code, repositories, users, issues, pull requests...

Provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server side websocket closed after a few seconds with read timeout error #2368

@RavikumarTulugu

RavikumarTulugu commented Dec 31, 2021

@madmongo1

madmongo1 commented Dec 31, 2021

Sorry, something went wrong.

RavikumarTulugu commented Jan 1, 2022

Ravikumartulugu commented jan 3, 2022 • edited, madmongo1 commented jan 3, 2022 • edited, ravikumartulugu commented jan 3, 2022, madmongo1 commented jan 3, 2022, ravikumartulugu commented jan 4, 2022.

@RavikumarTulugu

No branches or pull requests

@RavikumarTulugu

  • Function Reference
  • Other Services
  • Socket Functions

socket_set_option

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

socket_set_option — Sets socket options for the socket

Description

The socket_set_option() function sets the option specified by the option parameter, at the specified protocol level , to the value pointed to by the value parameter for the socket .

A Socket instance created with socket_create() or socket_accept() .

The level parameter specifies the protocol level at which the option resides. For example, to set options at the socket level, a level parameter of SOL_SOCKET would be used. Other levels, such as TCP, can be used by specifying the protocol number of that level. Protocol numbers can be found by using the getprotobyname() function.

The available socket options are the same as those for the socket_get_option() function.

The option value.

Return Values

Returns true on success or false on failure.

Example #1 socket_set_option() example

  • socket_create() - Create a socket (endpoint for communication)
  • socket_bind() - Binds a name to a socket
  • socket_strerror() - Return a string describing a socket error
  • socket_last_error() - Returns the last error on the socket
  • socket_get_option() - Gets socket options for the socket

User Contributed Notes 8 notes

To Top

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu , C++ Coding Standards

boost/asio/detail/socket_option.hpp

Revised $Date$

Copyright Beman Dawes, David Abrahams, 1998-2005.

Copyright Rene Rivera 2004-2008.

Distributed under the Boost Software License, Version 1.0 .

OSI Certified

IMAGES

  1. c++

    boost socket set_option timeout

  2. Python Socket

    boost socket set_option timeout

  3. Python Socket

    boost socket set_option timeout

  4. Sockets

    boost socket set_option timeout

  5. [Solved] set timeout for socket receive

    boost socket set_option timeout

  6. How to change boot menu list time on Windows 10

    boost socket set_option timeout

VIDEO

  1. Introducing socket #3

  2. VR1 Boost reed petal & manifold upgrade

  3. 2 heerlijke potjes 50+ kills😍

  4. How to on developer option in infinix smart 8HD, Enable developer mode, turn on developer mode

  5. Как Узнать В Какое Время ЛУЧШЕ Торговать? Бинарные опционы обучение

  6. How To Keep The Samsung Galaxy S24 Screen On

COMMENTS

  1. How to set a timeout on blocking sockets in boost asio?

    socket.set_option(boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO>{ 200 }); FULL ANSWER This question keep being asked over and over again for many years. Answers I saw so far are quite poor. I'll add this info right here in one of the first occurrences of this question.

  2. basic_socket::set_option (1 of 2 overloads)

    basic_socket::set_option (1 of 2 overloads) Set an option on the socket. template< typename SettableSocketOption > void set_option( const SettableSocketOption & option); This function is used to set an option on the socket.

  3. basic_socket::set_option (2 of 2 overloads)

    basic_socket::set_option (2 of 2 overloads) Set an option on the socket. template< typename SettableSocketOption > boost::system::error_code set_option( const SettableSocketOption & option, boost::system::error_code & ec); This function is used to set an option on the socket.

  4. ip::tcp::socket

    Description. broadcast. Socket option to permit sending of broadcast messages. bytes_readable. IO control command to get the amount of data that can be read without blocking. debug. Socket option to enable socket-level debugging. do_not_route. Socket option to prevent routing, use local interfaces only.

  5. basic_datagram_socket::set_option

    Boost C++ Libraries...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

  6. ip::udp::socket

    The UDP socket type. Socket option to permit sending of broadcast messages. IO control command to get the amount of data that can be read without blocking. Socket option to enable socket-level debugging. Socket option to prevent routing, use local interfaces only. Socket option to report aborted connections on accept.

  7. C++

    socket.set_option(boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO>{ 200 }); FULL ANSWER This question keep being asked over and over again for many years. Answers I saw so far are quite poor. I'll add this info right here in one of the first occurrences of this question.

  8. SO_RCVTIME and SO_RCVTIMEO not affecting Boost.Asio operations

    System Behavior. The SO_RCVTIMEO documentation notes that the option only affects system calls that perform socket I/O, such as read () and recvmsg (). It does not affect event demultiplexers, such as select () and poll (), that only watch the file descriptors to determine when I/O can occur without blocking.

  9. Timeouts ★

    The easiest way to turn them on is to set the suggested timeout settings on the stream. // Apply suggested timeout options for the server role to the stream ws. set_option (stream_base:: timeout:: suggested (role_type:: server)); For manual control over the settings, a timeout options object may be constructed.

  10. Socket Programming in C++ using boost.asio: TCP Server and Client

    More than two entities can also be set to communicate but by using multiple sockets. ... socket & socket, const string& message) { const string msg = message + " \n"; boost::asio::write( socket, boost::asio::buffer ... The other option is having an asynchronous server. We can start the operation, but we don't know when it will end, we don't ...

  11. c++

    I am required to set the options boost::asio::ip::tcp::no_delay and boost::asio::socket_base::linger for a boost::asio::ip::tcp::socket that connects to a remote TCP server. I used the method set_option in order to achieve this without any problems.. The question(s): once the io_service is run()ing and the socket opened, if I'm asked to change its options (i.e.: due to a change in the program ...

  12. Websocket

    Version of Beast 1.76.0 I've been trying to find a way to set a timeout without converting my entire code to async, and I've come across this code: get_lowest_layer (*_ws).set_option (boost::asio::detail::socket_option::integer<SOL_SOCKET,...

  13. Sync I/O operations with timeout · Issue #1764 · boostorg/beast

    Version of boost we are using: 1.71.0 Hi, we want to impement sync methods for ws with timeout, we already did this for the tcp socket using the async methods, just like in this example from boost asio and we wanted to try the same thing...

  14. server side websocket closed after a few seconds with read timeout

    This causes server to timeout as well. I am exploring whether i have to implement custom heartbeating myself. The client is a firefox web browser in this case. changing boost to 1.78 didnt help either. websocket::stream_base::timeout opt{std::chrono::seconds(30), std::chrono::seconds(300), true }; ws_.set_option(opt);

  15. C++ Boost ASIO: how to read/write with a timeout?

    To summarize, it is suggested to use asynchronous methods if you desire timeouts and cancellability. If you cannot convert to asynchronous methods, you might try the SO_RCVTIMEO and SO_SNDTIMEO socket options. They can be set with setsockopt, the descriptor can be obtained with the boost::asio::ip::tcp::socket::native method.

  16. ip::tcp::socket

    Description. broadcast. Socket option to permit sending of broadcast messages. bytes_readable. IO control command to get the amount of data that can be read without blocking. debug. Socket option to enable socket-level debugging. do_not_route. Socket option to prevent routing, use local interfaces only.

  17. Timeouts

    The easiest way to turn them on is to set the suggested timeout settings on the stream. // Apply suggested timeout options for the server role to the stream ws. set_option (stream_base:: timeout:: suggested (role_type:: server)); For manual control over the settings, a timeout options object may be constructed.

  18. PHP: socket_set_option

    Parameters. socket. A Socket instance created with socket_create() or socket_accept().. level. The level parameter specifies the protocol level at which the option resides. For example, to set options at the socket level, a level parameter of SOL_SOCKET would be used. Other levels, such as TCP, can be used by specifying the protocol number of that level.

  19. c++

    I am writing a socket application with Boost asio. Both the client and the server are using boost sockets. I see that, when the client sends a shutdown connection command: mysocket.shutdown( boost::asio::ip::tcp::socket::shutdown_both, error_code);, and my client C++ application closes down a 2 seconds later, I get TIME_WAIT on the output of ss ...

  20. Settable socket option requirements

    Settable socket option requirements. In the table below, X denotes a socket option class, a denotes a value of X, p denotes a value that meets the protocol requirements, and u denotes an identifier. Table 27. SettableSocketOption requirements. Returns a value suitable for passing as the level argument to POSIX setsockopt() (or equivalent).

  21. boost/asio/detail/socket_option.hpp

    boost/asio/detail/socket_option.hpp // // detail/socket_option.hpp // ~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com ...