Multiplexer that allows to read from multiple sockets. More...
#include <D:/private/SFML/SFML/include/SFML/Network/SocketSelector.hpp>
Public Types | |
| enum | : ReadinessType { Receive = 1 << 0 , Send = 1 << 1 } |
| Type of readiness to check for. More... | |
| using | ReadinessType = std::uint32_t |
| Bitwise combination of readiness types. | |
Public Member Functions | |
| SocketSelector () | |
| Default constructor. | |
| ~SocketSelector () | |
| Destructor. | |
| SocketSelector (const SocketSelector ©) | |
| Copy constructor. | |
| SocketSelector & | operator= (const SocketSelector &right) |
| Overload of assignment operator. | |
| SocketSelector (SocketSelector &&) noexcept | |
| Move constructor. | |
| SocketSelector & | operator= (SocketSelector &&) noexcept |
| Move assignment. | |
| bool | add (const Socket &socket, ReadinessType readinessType=Receive, std::function< void(ReadinessType readinessType)> readyCallback={}) |
| Add a new socket to the selector. | |
| bool | remove (const Socket &socket) |
| Remove a socket from the selector. | |
| void | clear () |
| Remove all the sockets stored in the selector. | |
| bool | wait (Time timeout=Time::Zero) |
| Wait until one or more sockets are ready to receive or send. | |
| bool | isReady (const Socket &socket, ReadinessType readinessType=Receive) const |
| Test a socket to know if it is ready to receive or send data. | |
| void | dispatchReadyCallbacks () |
| Dispatch callbacks of ready sockets. | |
Detailed Description
Multiplexer that allows to read from multiple sockets.
Socket selectors provide a way to wait until data can be received or sent on a set of sockets, instead of just one.
This is convenient when you have multiple sockets that may possibly receive data, but you don't know which one will be ready first. In particular, it avoids to use a thread for each socket; with selectors, a single thread can handle all the sockets. When sending large amounts of data, the socket send buffer might fill up and you will have to wait for the data to actually be sent over the network connection before attempting to send more data.
All types of sockets can be used in a selector:
A selector doesn't store its own copies of the sockets (socket classes are not copyable anyway), it simply keeps a reference to the original sockets that you pass to the "add" function. Therefore, you can't use the selector as a socket container, you must store them outside and make sure that they are alive as long as they are used in the selector.
Using a selector is simple:
- populate the selector with all the sockets that you want to observe
- make it wait until there is data available or data can be sent on any of the sockets
- test each socket to find out which ones are ready for receiving or sending
If scalability is a concern, using callbacks is also possible:
- add all the sockets that you want to observe to the selector with their own ready callbacks
- make the selector wait until there is data available or data can be sent on any of the sockets
- dispatch the callbacks of the sockets that became ready during the wait
Usage example:
Usage example with callbacks:
- See also
- sf::Socket
Definition at line 48 of file SocketSelector.hpp.
Member Typedef Documentation
◆ ReadinessType
| using sf::SocketSelector::ReadinessType = std::uint32_t |
Bitwise combination of readiness types.
Definition at line 51 of file SocketSelector.hpp.
Member Enumeration Documentation
◆ anonymous enum
| anonymous enum : ReadinessType |
Type of readiness to check for.
| Enumerator | |
|---|---|
| Receive | Check if sockets are ready to be received from. |
| Send | Check if sockets are ready to be sent to. |
Definition at line 57 of file SocketSelector.hpp.
Constructor & Destructor Documentation
◆ SocketSelector() [1/3]
| sf::SocketSelector::SocketSelector | ( | ) |
Default constructor.
◆ ~SocketSelector()
| sf::SocketSelector::~SocketSelector | ( | ) |
Destructor.
◆ SocketSelector() [2/3]
| sf::SocketSelector::SocketSelector | ( | const SocketSelector & | copy | ) |
Copy constructor.
- Parameters
-
copy Instance to copy
◆ SocketSelector() [3/3]
|
noexcept |
Move constructor.
Member Function Documentation
◆ add()
| bool sf::SocketSelector::add | ( | const Socket & | socket, |
| ReadinessType | readinessType = Receive, | ||
| std::function< void(ReadinessType readinessType)> | readyCallback = {} ) |
Add a new socket to the selector.
The type of readiness to wait for can be specified. Specifying SocketSelector::Receive will wait for the socket to become ready to receive data from, specifying SocketSelector::Send will wait for the socket to become ready to send data on. Specifying SocketSelector::Receive | SocketSelector::Send will wait for the socket to become either ready to send or receive data on.
Adding a socket after it has already been added will just overwrite the existing readiness type with the new value.
This function keeps a weak reference to the socket, so you have to make sure that the socket is not destroyed while it is stored in the selector. This function does nothing if the socket is not valid.
When adding a socket to the selector you can also attach a callback along with it. The callback is called by dispatchReadyCallbacks when a socket is determined to be ready after a call to wait.
Using attached callbacks instead of having to individually call isReady on every socket after every call to wait allows for scaling up to a large number of sockets. This is because the overhead of checking for socket readiness using isReady grows proportionally to the total number of sockets. When using callbacks calling isReady on every socket is no longer necessary.
Because a socket can be ready for receiving, sending or both, the type of readiness is passed to the attached callback as a bitwise combination of SocketSelector::Receive and/or SocketSelector::Send when it is called by dispatchReadyCallbacks. Some systems don't support combined read and write notifications. On these systems, if a socket is ready to be both received from and sent to the callback will be called twice, once with SocketSelector::Receive and once with SocketSelector::Send.
To remove the attached callback of a socket, call add again with an empty function.
By default, no readiness callback is attached when adding a socket.
- Parameters
-
socket Reference to the socket to add readinessType Type of readiness to wait for, a bitwise combination of SocketSelector::Receive and/or SocketSelector::Send readyCallback Ready callback to attach to the socket, pass an empty function to remove the ready callback
- Returns
- true if the socket was added successfully, false otherwise
◆ clear()
| void sf::SocketSelector::clear | ( | ) |
◆ dispatchReadyCallbacks()
| void sf::SocketSelector::dispatchReadyCallbacks | ( | ) |
Dispatch callbacks of ready sockets.
After calling wait returns true, at least one socket is ready to receive or send data. Calling dispatchReadyCallbacks will call the attached ready callback for every socket that is ready to either receive or send data. Sockets that don't have a callback attached can still be individually checked using isReady.
The readiness state of each socket is maintained until the next call to wait. Calling dispatchReadyCallbacks multiple times after a single call to wait will run the exact same callbacks with the exact same passed arguments.
- See also
- wait
◆ isReady()
|
nodiscard |
Test a socket to know if it is ready to receive or send data.
This function must be used after a call to wait, to know which sockets are ready to receive or send data. If a socket is ready, a call to receive or send will never block because we know that there is data available to read or we can write. Note that if this function returns true for a TcpListener, this means that it is ready to accept a new connection.
- Parameters
-
socket Socket to test readinessType Type of readiness to check for, a bitwise combination of SocketSelector::Receive and/or SocketSelector::Send
- Returns
- true if the socket is ready to read, false otherwise
- See also
- wait
◆ operator=() [1/2]
| SocketSelector & sf::SocketSelector::operator= | ( | const SocketSelector & | right | ) |
Overload of assignment operator.
- Parameters
-
right Instance to assign
- Returns
- Reference to self
◆ operator=() [2/2]
|
noexcept |
Move assignment.
◆ remove()
| bool sf::SocketSelector::remove | ( | const Socket & | socket | ) |
◆ wait()
|
nodiscard |
Wait until one or more sockets are ready to receive or send.
This function returns as soon as at least one socket has some data available to be received or data can be sent, depending on how the socket was added to this selector. To know which sockets are ready, use the isReady function. If you use a timeout and no socket is ready before the timeout is over, the function returns false.
- Parameters
-
timeout Maximum time to wait, (use Time::Zero for infinity)
- Returns
- true if there are sockets ready, false otherwise
- See also
- isReady, dispatchReadyCallbacks
The documentation for this class was generated from the following file: