SDL3pp
A slim C++ wrapper for SDL3
Loading...
Searching...
No Matches
A small cross-platform networking library

SDL_net is a simple library to help with networking. More...

Namespaces

namespace  SDL::prop
 Constants for Properties keys.

Classes

struct  SDL::AddressBase
 Base class to Address. More...
struct  SDL::Address
 Opaque representation of a computer-readable network address. More...
struct  SDL::StreamSocketBase
 Base class to StreamSocket. More...
struct  SDL::StreamSocket
 An object that represents a streaming connection to another system. More...
struct  SDL::ServerBase
 Base class to Server. More...
struct  SDL::Server
 The receiving end of a stream connection. More...
struct  SDL::DatagramSocketBase
 Base class to DatagramSocket. More...
struct  SDL::DatagramSocket
 An object that represents a datagram connection to another system. More...
struct  SDL::DatagramBase
 Base class to Datagram. More...
struct  SDL::Datagram
 The data provided for new incoming packets from ReceiveDatagram(). More...

Macros

#define SDL_NET_MAJOR_VERSION
 The current major version of the SDL_net headers.
#define SDL_NET_MINOR_VERSION
 The current minor version of the SDL_net headers.
#define SDL_NET_MICRO_VERSION
 The current micro (or patchlevel) version of the SDL_net headers.
#define SDL_NET_VERSION
 This is the version number macro for the current SDL_net version.
#define SDL_NET_VERSION_ATLEAST(X, Y, Z)
 This macro will evaluate to true if compiled with SDL_net at least X.Y.Z.

Typedefs

using SDL::AddressRaw = NET_Address*
 Alias to raw representation for Address.
using SDL::AddressRef = ResourceRefT<AddressBase>
 Reference for Address.
using SDL::StreamSocketRaw = NET_StreamSocket*
 Alias to raw representation for StreamSocket.
using SDL::StreamSocketRef = ResourceRefT<StreamSocketBase>
 Reference for StreamSocket.
using SDL::ServerRaw = NET_Server*
 Alias to raw representation for Server.
using SDL::ServerRef = ResourceRefT<ServerBase>
 Reference for Server.
using SDL::DatagramSocketRaw = NET_DatagramSocket*
 Alias to raw representation for DatagramSocket.
using SDL::DatagramSocketRef = ResourceRefT<DatagramSocketBase>
 Reference for DatagramSocket.
using SDL::DatagramRaw = NET_Datagram*
 Alias to raw representation for Datagram.
using SDL::DatagramRawConst = const NET_Datagram*
 Alias to const raw representation for Datagram.
using SDL::DatagramRef = ResourceRefT<DatagramBase>
 Reference for Datagram.
using SDL::DatagramConstRef = ResourceConstRef<DatagramRaw, DatagramRawConst>
 Safely wrap Datagram for non owning const parameters.
using SDL::Status = NET_Status
 A tri-state for asynchronous operations.
using SDL::LocalAddressesArray = OwnArray<AddressRef, LocalAddressesArrayDeleter>
 Array of addresses returned by GetLocalAddresses.

Functions

Address SDL::ResolveHostname (StringParam host)
 Resolve a human-readable hostname.
Status SDL::WaitUntilResolved (AddressRef address, Sint32 timeout)
 Block until an address is resolved.
Status SDL::GetAddressStatus (AddressRef address)
 Check if an address is resolved, without blocking.
const char * SDL::GetAddressString (AddressRef address)
 Get a human-readable string from a resolved address.
const void * SDL::GetAddressBytes (AddressRef address, int *num_bytes)
 Get the protocol-level bytes of a network address from a resolved address.
Address SDL::RefAddress (AddressRef address)
 Add a reference to an Address.
void SDL::UnrefAddress (AddressRaw address)
 Drop a reference to an Address.
void SDL::SimulateAddressResolutionLoss (int percent_loss)
 Enable simulated address resolution failures.
int SDL::CompareAddresses (AddressRef a, AddressRef b)
 Compare two Address objects.
LocalAddressesArray SDL::GetLocalAddresses ()
 Obtain a list of local addresses on the system.
void SDL::FreeLocalAddresses (AddressRef *addresses)
 Free the results from GetLocalAddresses.
StreamSocket SDL::CreateClient (AddressRef address, Uint16 port, PropertiesRef props)
 Begin connecting a socket as a client to a remote server.
Status SDL::WaitUntilConnected (StreamSocketRef sock, Sint32 timeout)
 Block until a stream socket has connected to a server.
Server SDL::CreateServer (AddressRef addr, Uint16 port, PropertiesRef props)
 Create a server, which listens for connections to accept.
void SDL::AcceptClient (ServerRef server, NET_StreamSocket **client_stream)
 Create a stream socket for the next pending client connection.
void SDL::DestroyServer (ServerRaw server)
 Dispose of a previously-created server.
Address SDL::GetStreamSocketAddress (StreamSocketRef sock)
 Get the remote address of a stream socket.
Status SDL::GetConnectionStatus (StreamSocketRef sock)
 Check if a stream socket is connected, without blocking.
bool SDL::WriteToStreamSocket (StreamSocketRef sock, const void *buf, int buflen)
 Send bytes over a stream socket to a remote system.
int SDL::GetStreamSocketPendingWrites (StreamSocketRef sock)
 Query bytes still pending transmission on a stream socket.
int SDL::WaitUntilStreamSocketDrained (StreamSocketRef sock, Sint32 timeout)
 Block until all of a stream socket's pending data is sent.
int SDL::ReadFromStreamSocket (StreamSocketRef sock, void *buf, int buflen)
 Receive bytes that a remote system sent to a stream socket.
void SDL::SimulateStreamPacketLoss (StreamSocketRef sock, int percent_loss)
 Enable simulated stream socket failures.
void SDL::DestroyStreamSocket (StreamSocketRaw sock)
 Dispose of a previously-created stream socket.
DatagramSocket SDL::CreateDatagramSocket (AddressRef addr, Uint16 port, PropertiesRef props)
 Create and bind a new datagram socket.
bool SDL::SendDatagram (DatagramSocketRef sock, AddressRef address, Uint16 port, const void *buf, int buflen)
 Send a new packet over a datagram socket to a remote system.
bool SDL::ReceiveDatagram (DatagramSocketRef sock, Datagram &dgram)
 Receive a new packet that a remote system sent to a datagram socket.
Datagram SDL::ReceiveDatagram (DatagramSocketRef sock)
 Receive a new packet that a remote system sent to a datagram socket.
void SDL::DestroyDatagram (DatagramRaw dgram)
 Dispose of a datagram packet previously received.
void SDL::SimulateDatagramPacketLoss (DatagramSocketRef sock, int percent_loss)
 Enable simulated datagram socket failures.
void SDL::DestroyDatagramSocket (DatagramSocketRaw sock)
 Dispose of a previously-created datagram socket.
int SDL::WaitUntilInputAvailable (void **vsockets, int numsockets, Sint32 timeout)
 Block on multiple sockets until at least one has data available.
 SDL::Address::Address (StringParam host)
 Resolve a human-readable hostname.
 SDL::Address::Address (const Address &address)
 Add a reference to an Address.
Status SDL::AddressBase::WaitUntilResolved (Sint32 timeout)
 Block until an address is resolved.
Status SDL::AddressBase::GetStatus ()
 Check if an address is resolved, without blocking.
const char * SDL::AddressBase::GetString ()
 Get a human-readable string from a resolved address.
const void * SDL::AddressBase::GetBytes (int *num_bytes)
 Get the protocol-level bytes of a network address from a resolved address.
void SDL::AddressBase::Unref ()
 Drop a reference to an Address.
int SDL::AddressBase::Compare (AddressRef b) const
 Compare two Address objects.
bool SDL::AddressBase::operator== (const AddressBase &other) const
 Compares two addresses for equality.
auto SDL::AddressBase::operator<=> (const AddressBase &other) const
 Compares two addresses.
StreamSocket SDL::AddressBase::CreateClient (Uint16 port, PropertiesRef props)
 Begin connecting a socket as a client to a remote server.
 SDL::StreamSocket::StreamSocket (AddressRef address, Uint16 port, PropertiesRef props)
 Begin connecting a socket as a client to a remote server.
Status SDL::StreamSocketBase::WaitUntilConnected (Sint32 timeout)
 Block until a stream socket has connected to a server.
Server SDL::AddressBase::CreateServer (Uint16 port, PropertiesRef props)
 Create a server, which listens for connections to accept.
 SDL::Server::Server (AddressRef addr, Uint16 port, PropertiesRef props)
 Create a server, which listens for connections to accept.
void SDL::ServerBase::AcceptClient (NET_StreamSocket **client_stream)
 Create a stream socket for the next pending client connection.
void SDL::ServerBase::Destroy ()
 Dispose of a previously-created server.
Address SDL::StreamSocketBase::GetAddress ()
 Get the remote address of a stream socket.
Status SDL::StreamSocketBase::GetConnectionStatus ()
 Check if a stream socket is connected, without blocking.
bool SDL::StreamSocketBase::WriteTo (const void *buf, int buflen)
 Send bytes over a stream socket to a remote system.
int SDL::StreamSocketBase::GetPendingWrites ()
 Query bytes still pending transmission on a stream socket.
int SDL::StreamSocketBase::WaitUntilDrained (Sint32 timeout)
 Block until all of a stream socket's pending data is sent.
int SDL::StreamSocketBase::ReadFrom (void *buf, int buflen)
 Receive bytes that a remote system sent to a stream socket.
void SDL::StreamSocketBase::SimulateStreamPacketLoss (int percent_loss)
 Enable simulated stream socket failures.
void SDL::StreamSocketBase::Destroy ()
 Dispose of a previously-created stream socket.
DatagramSocket SDL::AddressBase::CreateDatagramSocket (Uint16 port, PropertiesRef props)
 Create and bind a new datagram socket.
 SDL::DatagramSocket::DatagramSocket (AddressRef addr, Uint16 port, PropertiesRef props)
 Create and bind a new datagram socket.
bool SDL::DatagramSocketBase::SendDatagram (AddressRef address, Uint16 port, const void *buf, int buflen)
 Send a new packet over a datagram socket to a remote system.
bool SDL::DatagramSocketBase::ReceiveDatagram (Datagram &dgram)
 Receive a new packet that a remote system sent to a datagram socket.
Datagram SDL::DatagramSocketBase::ReceiveDatagram ()
 Receive a new packet that a remote system sent to a datagram socket.
 SDL::Datagram::Datagram (DatagramSocketRef sock)
 Receive a new packet that a remote system sent to a datagram socket.
bool SDL::DatagramBase::Receive (DatagramSocketRef sock)
 Receive a new packet that a remote system sent to a datagram socket.
void SDL::DatagramBase::Destroy ()
 Dispose of a datagram packet previously received.
void SDL::DatagramSocketBase::SimulateDatagramPacketLoss (int percent_loss)
 Enable simulated datagram socket failures.
void SDL::DatagramSocketBase::Destroy ()
 Dispose of a previously-created datagram socket.

Variables

constexpr Status SDL::FAILURE
 Async operation complete, result was failure.
constexpr Status SDL::WAITING = NET_WAITING
 Async operation is still in progress, check again later.
constexpr Status SDL::SUCCESS
 Async operation complete, result was success.

Detailed Description

SDL_net is a simple library to help with networking.

In current times, it's a relatively thin layer over system-level APIs like BSD Sockets or WinSock. Its primary strength is in making those interfaces less complicated to use, and handling several unexpected corner cases, so the app doesn't have to.

Some design philosophies of SDL_net:

  • Nothing is blocking (but you can explicitly wait on things if you want).
  • Addressing is abstract so you don't have to worry about specific networks and their specific protocols.
  • Simple is better than hard, and not necessarily less powerful either.

There are several pieces to this library, and most apps won't use them all, but rather choose the portion that's relevant to their needs.

All apps will call NET.Init() on startup and NET.Quit() on shutdown.

The cornerstone of the library is the Address object. This is what manages the details of how to reach another computer on the network, and what network protocol to use to get there. You'll need a Address to talk over the network. If you need to convert a hostname (such as "google.com" or "libsdl.org") into a Address, you can call ResolveHostname(), which will do the appropriate DNS queries on a background thread. Once these are ready, you can use the Address to connect to these hosts over the Internet.

Something that initiates a connection to a remote system is called a "client," connecting to a "server." To establish a connection, use the Address you resolved with CreateClient(). Once the connection is established (a non-blocking operation), you'll have a StreamSocket object that can send and receive data over the connection, using WriteToStreamSocket() and ReadFromStreamSocket().

To instead be a server, that clients connect to, call CreateServer() to get a Server object. All a Server does is allow you to accept connections from clients, turning them into NET_StreamSockets, where you can read and write from the opposite side of the connection from a given client.

These things are, underneath this API, TCP connections, which means you can use a client or server to talk to something that isn't using SDL_net at all.

Clients and servers deal with "stream sockets," a reliable stream of bytes. There are tradeoffs to using these, especially in poor network conditions. Another option is to use "datagram sockets," which map to UDP packet transmission. With datagrams, everyone involved can send small packets of data that may arrive in any order, or not at all, but transmission can carry on if a packet is lost, each packet is clearly separated from every other, and communication can happen in a peer-to-peer model instead of client-server: while datagrams can be more complex, these are useful properties not avaiable to stream sockets. CreateDatagramSocket() is used to prepare for datagram communication, then SendDatagram() and ReceiveDatagram() transmit packets.

As previously mentioned, SDL_net's API is "non-blocking" (asynchronous). Any network operation might take time, but SDL_net's APIs will not wait until they complete. Any operation will return immediately, with options to check if the operation has completed later. Generally this is what a video game needs, but there are times where it makes sense to pause until an operation completes; in a background thread this might make sense, as it could simplify the code dramatically.

The functions that block until an operation completes:

  • WaitUntilConnected
  • WaitUntilInputAvailable
  • WaitUntilResolved
  • WaitUntilStreamSocketDrained

All of these functions offer a timeout, which allow for a maximum wait time, an immediate non-blocking query, or an infinite wait.

Finally, SDL_net offers a way to simulate network problems, to test the always-less-than-ideal conditions in the real world. One can programmatically make the app behave like it's on a flakey wifi connection even if it's running wired directly to a gigabit fiber line. The functions:

  • SimulateAddressResolutionLoss
  • SimulateStreamPacketLoss
  • SimulateDatagramPacketLoss

Macro Definition Documentation

◆ SDL_NET_MAJOR_VERSION

#define SDL_NET_MAJOR_VERSION

The current major version of the SDL_net headers.

If this were SDL_net version 3.2.1, this value would be 3.

Since
This macro is available since SDL_net 3.0.0.

◆ SDL_NET_MICRO_VERSION

#define SDL_NET_MICRO_VERSION

The current micro (or patchlevel) version of the SDL_net headers.

If this were SDL_net version 3.2.1, this value would be 1.

Since
This macro is available since SDL_net 3.0.0.

◆ SDL_NET_MINOR_VERSION

#define SDL_NET_MINOR_VERSION

The current minor version of the SDL_net headers.

If this were SDL_net version 3.2.1, this value would be 2.

Since
This macro is available since SDL_net 3.0.0.

◆ SDL_NET_VERSION

#define SDL_NET_VERSION
Value:
#define SDL_NET_MAJOR_VERSION
The current major version of the SDL_net headers.
Definition SDL3pp_net.h:196
#define SDL_NET_MICRO_VERSION
The current micro (or patchlevel) version of the SDL_net headers.
Definition SDL3pp_net.h:214
#define SDL_NET_MINOR_VERSION
The current minor version of the SDL_net headers.
Definition SDL3pp_net.h:205
#define SDL_VERSIONNUM(major, minor, patch)
This macro turns the version numbers into a numeric value.
Definition SDL3pp_version.h:57

This is the version number macro for the current SDL_net version.

Since
This macro is available since SDL_net 3.0.0.
See also
NET.Version

◆ SDL_NET_VERSION_ATLEAST

#define SDL_NET_VERSION_ATLEAST ( X,
Y,
Z )
Value:

This macro will evaluate to true if compiled with SDL_net at least X.Y.Z.

Since
This macro is available since SDL_net 3.0.0.

Typedef Documentation

◆ AddressRef

Reference for Address.

This does not take ownership!

◆ DatagramRef

Reference for Datagram.

This does not take ownership!

◆ DatagramSocketRef

Reference for DatagramSocket.

This does not take ownership!

◆ LocalAddressesArray

using SDL::LocalAddressesArray = OwnArray<AddressRef, LocalAddressesArrayDeleter>

Array of addresses returned by GetLocalAddresses.

The array is freed automatically when it goes out of scope.

◆ ServerRef

Reference for Server.

This does not take ownership!

◆ Status

using SDL::Status = NET_Status

A tri-state for asynchronous operations.

Lots of tasks in SDL_net are asynchronous, as they can't complete until data passes over a network at some murky future point in time.

This includes sending data over a stream socket, resolving a hostname, connecting to a remote system, and other tasks.

The library never blocks on tasks that take time to complete, with the exception of functions named "Wait", which are intended to do nothing but block until a task completes. Functions that are attempting to do something that might block, or are querying the status of a task in-progress, will return a Status, so an app can see if a task completed, and its final outcome.

Since
This enum is available since SDL_net 3.0.0.

◆ StreamSocketRef

Reference for StreamSocket.

This does not take ownership!

Function Documentation

◆ AcceptClient() [1/2]

void SDL::AcceptClient ( ServerRef server,
NET_StreamSocket ** client_stream )
inline

Create a stream socket for the next pending client connection.

When a client connects to a server, their connection will be pending until the server accepts the connection. Once accepted, the server will be given a stream socket to communicate with the client, and they can send data to, and receive data from, each other.

Unlike CreateClient, stream sockets returned from this function are already connected and do not have to wait for the connection to complete, as server acceptance is the final step of connecting.

This function does not block. If there are no new connections pending, this function will return true (for success, but *client_stream will be set to nullptr. This is not an error and a common condition the app should expect. In fact, this function should be called in a loop until this condition occurs, so all pending connections are accepted in a single batch.

If you want the server to sleep until there's a new connection, you can use WaitUntilInputAvailable().

When done with the newly-accepted client, you can disconnect and dispose of the stream socket by calling DestroyStreamSocket().

Parameters
serverthe server object to check for pending connections.
client_streamWill be set to a new stream socket if a connection was pending, nullptr otherwise.
Exceptions
Erroron failure.
Thread safety:
You should not operate on the same server from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different servers at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilInputAvailable
DestroyStreamSocket

◆ AcceptClient() [2/2]

void SDL::ServerBase::AcceptClient ( NET_StreamSocket ** client_stream)
inline

Create a stream socket for the next pending client connection.

When a client connects to a server, their connection will be pending until the server accepts the connection. Once accepted, the server will be given a stream socket to communicate with the client, and they can send data to, and receive data from, each other.

Unlike CreateClient, stream sockets returned from this function are already connected and do not have to wait for the connection to complete, as server acceptance is the final step of connecting.

This function does not block. If there are no new connections pending, this function will return true (for success, but *client_stream will be set to nullptr. This is not an error and a common condition the app should expect. In fact, this function should be called in a loop until this condition occurs, so all pending connections are accepted in a single batch.

If you want the server to sleep until there's a new connection, you can use WaitUntilInputAvailable().

When done with the newly-accepted client, you can disconnect and dispose of the stream socket by calling DestroyStreamSocket().

Parameters
client_streamWill be set to a new stream socket if a connection was pending, nullptr otherwise.
Exceptions
Erroron failure.
Thread safety:
You should not operate on the same server from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different servers at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilInputAvailable
DestroyStreamSocket

◆ Address() [1/2]

SDL::Address::Address ( const Address & address)
inline

Add a reference to an Address.

Since several pieces of the library might share a single Address, including a background thread that's working on resolving, these objects are referenced counted. This allows everything that's using it to declare they still want it, and drop their reference to the address when they are done with it. The object's resources are freed when the last reference is dropped.

This function adds a reference to an Address, increasing its reference count by one.

The documentation will tell you when the app has to explicitly unref an address. For example, ResolveHostname() creates addresses that are already referenced, so the caller needs to unref it when done.

Generally you only have to explicit ref an address when you have different parts of your own app that will be sharing an address. In normal usage, you only have to unref things you've created once (like you might free() something), but you are free to add extra refs if it makes sense.

This returns the same address passed as a parameter, which makes it easy to ref and assign in one step:

myAddr = RefAddress(yourAddr);
Address RefAddress(AddressRef address)
Add a reference to an Address.
Definition SDL3pp_net.h:1146
Parameters
addressThe Address to add a reference to.
Postcondition
the same address that was passed as a parameter.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ Address() [2/2]

SDL::Address::Address ( StringParam host)
inline

Resolve a human-readable hostname.

SDL_net doesn't operate on human-readable hostnames (like www.libsdl.org but on computer-readable addresses. This function converts from one to the other. This process is known as "resolving" an address.

You can also use this to turn IP address strings (like "159.203.69.7") into Address objects.

Note that resolving an address is an asynchronous operation, since the library will need to ask a server on the internet to get the information it needs, and this can take time (and possibly fail later). This function will not block. It either returns nullptr (catastrophic failure) or an unresolved Address. Until the address resolves, it can't be used.

If you want to block until the resolution is finished, you can call WaitUntilResolved(). Otherwise, you can do a non-blocking check with GetAddressStatus().

When you are done with the returned Address, call UnrefAddress() to dispose of it. You need to do this even if resolution later fails asynchronously.

Parameters
hostThe hostname to resolve.
Postcondition
A new Address on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilResolved
GetAddressStatus
RefAddress
UnrefAddress

◆ Compare()

int SDL::AddressBase::Compare ( AddressRef b) const
inline

Compare two Address objects.

This compares two addresses, returning a value that is useful for qsort (or qsort).

Parameters
bsecond address to compare.
Returns
a value less than zero if a is "less than" b, a value greater than zero if "greater than", zero if equal.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ CompareAddresses()

int SDL::CompareAddresses ( AddressRef a,
AddressRef b )
inline

Compare two Address objects.

This compares two addresses, returning a value that is useful for qsort (or qsort).

Parameters
afirst address to compare.
bsecond address to compare.
Returns
a value less than zero if a is "less than" b, a value greater than zero if "greater than", zero if equal.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ CreateClient() [1/2]

StreamSocket SDL::AddressBase::CreateClient ( Uint16 port,
PropertiesRef props )
inline

Begin connecting a socket as a client to a remote server.

Each StreamSocket represents a single connection between systems. Usually, a client app will have one connection to a server app on a different computer, and the server app might have many connections from different clients. Each of these connections communicate over a separate stream socket.

Connecting is an asynchronous operation; this function does not block, and will return before the connection is complete. One has to then use WaitUntilConnected() or GetConnectionStatus() to see when the operation has completed, and if it was successful.

Once connected, you can read and write data to the returned socket. Stream sockets are a mode of reliable transmission, which means data will be received as a stream of bytes in the order you sent it. If there are problems in transmission, the system will deal with protocol negotiation and retransmission as necessary, transparent to your app, but this means until data is available in the order sent, the remote side will not get any new data. This is the tradeoff vs datagram sockets, where data can arrive in any order, or not arrive at all, without waiting, but the sender will not know.

Stream sockets don't employ any protocol (above the TCP level), so they can connect to servers that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

This function will fail if address is not finished resolving.

When you are done with this connection (whether it failed to connect or not), you must dispose of it with DestroyStreamSocket().

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

There are currently no extra properties for creating a client, so props should be zero. A future revision of SDL_net may add additional (optional) properties.

Parameters
portthe port on the remote server to connect to.
propsproperties of the new client. Specify zero for defaults.
Returns
pending connection on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilConnected
GetConnectionStatus
DestroyStreamSocket

◆ CreateClient() [2/2]

StreamSocket SDL::CreateClient ( AddressRef address,
Uint16 port,
PropertiesRef props )
inline

Begin connecting a socket as a client to a remote server.

Each StreamSocket represents a single connection between systems. Usually, a client app will have one connection to a server app on a different computer, and the server app might have many connections from different clients. Each of these connections communicate over a separate stream socket.

Connecting is an asynchronous operation; this function does not block, and will return before the connection is complete. One has to then use WaitUntilConnected() or GetConnectionStatus() to see when the operation has completed, and if it was successful.

Once connected, you can read and write data to the returned socket. Stream sockets are a mode of reliable transmission, which means data will be received as a stream of bytes in the order you sent it. If there are problems in transmission, the system will deal with protocol negotiation and retransmission as necessary, transparent to your app, but this means until data is available in the order sent, the remote side will not get any new data. This is the tradeoff vs datagram sockets, where data can arrive in any order, or not arrive at all, without waiting, but the sender will not know.

Stream sockets don't employ any protocol (above the TCP level), so they can connect to servers that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

This function will fail if address is not finished resolving.

When you are done with this connection (whether it failed to connect or not), you must dispose of it with DestroyStreamSocket().

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

There are currently no extra properties for creating a client, so props should be zero. A future revision of SDL_net may add additional (optional) properties.

Parameters
addressthe address of the remote server to connect to.
portthe port on the remote server to connect to.
propsproperties of the new client. Specify zero for defaults.
Returns
pending connection on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilConnected
GetConnectionStatus
DestroyStreamSocket

◆ CreateDatagramSocket() [1/2]

DatagramSocket SDL::AddressBase::CreateDatagramSocket ( Uint16 port,
PropertiesRef props )
inline

Create and bind a new datagram socket.

Datagram sockets follow different rules than stream sockets. They are not a reliable stream of bytes but rather packets, they are not limited to talking to a single other remote system, they do not maintain a single "connection" that can be dropped, and they are more nimble about network failures at the expense of being more complex to use. What makes sense for your app depends entirely on what your app is trying to accomplish.

Generally the idea of a datagram socket is that you send data one chunk ("packet") at a time to any address you want, and it arrives whenever it gets there, even if later packets get there first, and maybe it doesn't get there at all, and you don't know when anything of this happens by default.

This function creates a new datagram socket.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a socket or not. If this returns success, you can immediately start talking to the network.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

If you need to bind to a specific port (like a server), you should specify it in the port argument; datagram servers should do this, so they can be reached at a well-known port. If you only plan to initiate communications (like a client), you should specify 0 and let the system pick an unused port. Only one process can bind to a specific port at a time, so if you aren't acting as a server, you should choose 0. Datagram sockets can send individual packets to any port, so this just declares where data will arrive for your socket.

Datagram sockets don't employ any protocol (above the UDP level), so they can talk to apps that aren't using SDL_net, but if you want to speak any protocol beyond arbitrary packets of bytes, such as WebRTC, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.DatagramSocket.REUSEADDR_BOOLEAN: true if the socket should be created even if a previous socket has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, socket creation will fail and this function will report an error.
  • prop.DatagramSocket.ALLOW_BROADCAST_BOOLEAN: true if the socket should allow broadcasting. At the lower level, this will set SO_BROADCAST for IPv4 sockets, to allow sending to the subnet's broadcast address at the OS level. For IPv6, it'll join the all-nodes link-local multicast group, ff02::1, allowing sending and receiving there, more or less simulating the usual IPv4 broadcast semantics. Other protocols take similar approaches. If you do not intend to send or receive broadcast packets on this socket, set this property to false, or omit it, as it defaults to false. Note: IPv4 will still be able to receive broadcast packets without this option, but IPv6 will not. Also see notes about sending to a broadcast address in SendDatagram().
Parameters
portthe port on the local address to listen for connections on, or zero for the system to decide.
propsproperties of the new socket. Specify zero for defaults.
Returns
a new DatagramSocket on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
DestroyDatagramSocket

◆ CreateDatagramSocket() [2/2]

DatagramSocket SDL::CreateDatagramSocket ( AddressRef addr,
Uint16 port,
PropertiesRef props )
inline

Create and bind a new datagram socket.

Datagram sockets follow different rules than stream sockets. They are not a reliable stream of bytes but rather packets, they are not limited to talking to a single other remote system, they do not maintain a single "connection" that can be dropped, and they are more nimble about network failures at the expense of being more complex to use. What makes sense for your app depends entirely on what your app is trying to accomplish.

Generally the idea of a datagram socket is that you send data one chunk ("packet") at a time to any address you want, and it arrives whenever it gets there, even if later packets get there first, and maybe it doesn't get there at all, and you don't know when anything of this happens by default.

This function creates a new datagram socket.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a socket or not. If this returns success, you can immediately start talking to the network.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

If you need to bind to a specific port (like a server), you should specify it in the port argument; datagram servers should do this, so they can be reached at a well-known port. If you only plan to initiate communications (like a client), you should specify 0 and let the system pick an unused port. Only one process can bind to a specific port at a time, so if you aren't acting as a server, you should choose 0. Datagram sockets can send individual packets to any port, so this just declares where data will arrive for your socket.

Datagram sockets don't employ any protocol (above the UDP level), so they can talk to apps that aren't using SDL_net, but if you want to speak any protocol beyond arbitrary packets of bytes, such as WebRTC, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.DatagramSocket.REUSEADDR_BOOLEAN: true if the socket should be created even if a previous socket has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, socket creation will fail and this function will report an error.
  • prop.DatagramSocket.ALLOW_BROADCAST_BOOLEAN: true if the socket should allow broadcasting. At the lower level, this will set SO_BROADCAST for IPv4 sockets, to allow sending to the subnet's broadcast address at the OS level. For IPv6, it'll join the all-nodes link-local multicast group, ff02::1, allowing sending and receiving there, more or less simulating the usual IPv4 broadcast semantics. Other protocols take similar approaches. If you do not intend to send or receive broadcast packets on this socket, set this property to false, or omit it, as it defaults to false. Note: IPv4 will still be able to receive broadcast packets without this option, but IPv6 will not. Also see notes about sending to a broadcast address in SendDatagram().
Parameters
addrthe local address to listen for connections on, or nullptr to listen on all available local addresses.
portthe port on the local address to listen for connections on, or zero for the system to decide.
propsproperties of the new socket. Specify zero for defaults.
Returns
a new DatagramSocket on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
DestroyDatagramSocket

◆ CreateServer() [1/2]

Server SDL::AddressBase::CreateServer ( Uint16 port,
PropertiesRef props )
inline

Create a server, which listens for connections to accept.

An app that initiates connection to a remote computer is called a "client," and the thing the client connects to is called a "server."

Servers listen for and accept connections from clients, which spawns a new stream socket on the server's end, which it can then send/receive data on.

Use this function to create a server that will accept connections from other systems.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a server or not. If this returns success, you can immediately start accepting connections.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

After creating a server, you get stream sockets to talk to incoming client connections by calling AcceptClient().

Stream sockets don't employ any protocol (above the TCP level), so they can accept connections from clients that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.Server.REUSEADDR_BOOLEAN: true if the server should be created even if a previous server has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, server creation will fail and this function will report an error.
Parameters
portthe port on the local address to listen for connections on.
propsproperties of the new server. Specify zero for defaults.
Returns
a new Server on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
AcceptClient
DestroyServer

◆ CreateServer() [2/2]

Server SDL::CreateServer ( AddressRef addr,
Uint16 port,
PropertiesRef props )
inline

Create a server, which listens for connections to accept.

An app that initiates connection to a remote computer is called a "client," and the thing the client connects to is called a "server."

Servers listen for and accept connections from clients, which spawns a new stream socket on the server's end, which it can then send/receive data on.

Use this function to create a server that will accept connections from other systems.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a server or not. If this returns success, you can immediately start accepting connections.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

After creating a server, you get stream sockets to talk to incoming client connections by calling AcceptClient().

Stream sockets don't employ any protocol (above the TCP level), so they can accept connections from clients that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.Server.REUSEADDR_BOOLEAN: true if the server should be created even if a previous server has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, server creation will fail and this function will report an error.
Parameters
addrthe local address to listen for connections on, or nullptr.
portthe port on the local address to listen for connections on.
propsproperties of the new server. Specify zero for defaults.
Returns
a new Server on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
AcceptClient
DestroyServer

◆ Datagram()

SDL::Datagram::Datagram ( DatagramSocketRef sock)
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with DestroyDatagramSocket().

Parameters
sockthe datagram socket to send data through.
Postcondition
a valid Datagram object if data sent or queued for transmission, nullptr on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ DatagramSocket()

SDL::DatagramSocket::DatagramSocket ( AddressRef addr,
Uint16 port,
PropertiesRef props )
inline

Create and bind a new datagram socket.

Datagram sockets follow different rules than stream sockets. They are not a reliable stream of bytes but rather packets, they are not limited to talking to a single other remote system, they do not maintain a single "connection" that can be dropped, and they are more nimble about network failures at the expense of being more complex to use. What makes sense for your app depends entirely on what your app is trying to accomplish.

Generally the idea of a datagram socket is that you send data one chunk ("packet") at a time to any address you want, and it arrives whenever it gets there, even if later packets get there first, and maybe it doesn't get there at all, and you don't know when anything of this happens by default.

This function creates a new datagram socket.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a socket or not. If this returns success, you can immediately start talking to the network.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

If you need to bind to a specific port (like a server), you should specify it in the port argument; datagram servers should do this, so they can be reached at a well-known port. If you only plan to initiate communications (like a client), you should specify 0 and let the system pick an unused port. Only one process can bind to a specific port at a time, so if you aren't acting as a server, you should choose 0. Datagram sockets can send individual packets to any port, so this just declares where data will arrive for your socket.

Datagram sockets don't employ any protocol (above the UDP level), so they can talk to apps that aren't using SDL_net, but if you want to speak any protocol beyond arbitrary packets of bytes, such as WebRTC, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.DatagramSocket.REUSEADDR_BOOLEAN: true if the socket should be created even if a previous socket has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, socket creation will fail and this function will report an error.
  • prop.DatagramSocket.ALLOW_BROADCAST_BOOLEAN: true if the socket should allow broadcasting. At the lower level, this will set SO_BROADCAST for IPv4 sockets, to allow sending to the subnet's broadcast address at the OS level. For IPv6, it'll join the all-nodes link-local multicast group, ff02::1, allowing sending and receiving there, more or less simulating the usual IPv4 broadcast semantics. Other protocols take similar approaches. If you do not intend to send or receive broadcast packets on this socket, set this property to false, or omit it, as it defaults to false. Note: IPv4 will still be able to receive broadcast packets without this option, but IPv6 will not. Also see notes about sending to a broadcast address in SendDatagram().
Parameters
addrthe local address to listen for connections on, or nullptr to listen on all available local addresses.
portthe port on the local address to listen for connections on, or zero for the system to decide.
propsproperties of the new socket. Specify zero for defaults.
Postcondition
a new DatagramSocket on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
DestroyDatagramSocket

◆ Destroy() [1/4]

void SDL::DatagramBase::Destroy ( )
inline

Dispose of a datagram packet previously received.

You must pass packets received through ReceiveDatagram to this function when you are done with them. This will free resources used by this packet and unref its Address.

If you want to save the sender's address from the packet past this time, it is safe to call RefAddress() on the address and hold onto its pointer, so long as you call UnrefAddress() on it when you are done with it.

Once you call this function, the datagram pointer becomes invalid and should not be used again by the app.

Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ Destroy() [2/4]

void SDL::DatagramSocketBase::Destroy ( )
inline

Dispose of a previously-created datagram socket.

This will abandon any data queued for sending that hasn't made it to the socket. If you need this data to arrive, you should wait for confirmation from the remote computer in some form that you devise yourself. Queued data is not guaranteed to arrive even if the library made efforts to transmit it here.

Any data that has arrived from the remote end of the connection that hasn't been read yet is lost.

Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateDatagramSocket
SendDatagram
ReceiveDatagram

◆ Destroy() [3/4]

void SDL::ServerBase::Destroy ( )
inline

Dispose of a previously-created server.

This will immediately disconnect any pending client connections that had not yet been accepted, but will not disconnect any existing accepted connections (which can still be used and must be destroyed separately). Further attempts to make new connections to this server will fail on the client side.

Thread safety:
You should not operate on the same server from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different servers at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateServer

◆ Destroy() [4/4]

void SDL::StreamSocketBase::Destroy ( )
inline

Dispose of a previously-created stream socket.

This will immediately disconnect the other side of the connection, if necessary. Further attempts to read or write the socket on the remote end will fail.

This will abandon any data queued for sending that hasn't made it to the socket. If you need this data to arrive, you should wait for it to transmit before destroying the socket with GetStreamSocketPendingWrites() or WaitUntilStreamSocketDrained(). Any data that has arrived from the remote end of the connection that hasn't been read yet is lost.

Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateClient
AcceptClient
GetStreamSocketPendingWrites
WaitUntilStreamSocketDrained

◆ DestroyDatagram()

void SDL::DestroyDatagram ( DatagramRaw dgram)
inline

Dispose of a datagram packet previously received.

You must pass packets received through ReceiveDatagram to this function when you are done with them. This will free resources used by this packet and unref its Address.

If you want to save the sender's address from the packet past this time, it is safe to call RefAddress() on the address and hold onto its pointer, so long as you call UnrefAddress() on it when you are done with it.

Once you call this function, the datagram pointer becomes invalid and should not be used again by the app.

Parameters
dgramthe datagram packet to destroy.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ DestroyDatagramSocket()

void SDL::DestroyDatagramSocket ( DatagramSocketRaw sock)
inline

Dispose of a previously-created datagram socket.

This will abandon any data queued for sending that hasn't made it to the socket. If you need this data to arrive, you should wait for confirmation from the remote computer in some form that you devise yourself. Queued data is not guaranteed to arrive even if the library made efforts to transmit it here.

Any data that has arrived from the remote end of the connection that hasn't been read yet is lost.

Parameters
sockdatagram socket to destroy.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateDatagramSocket
SendDatagram
ReceiveDatagram

◆ DestroyServer()

void SDL::DestroyServer ( ServerRaw server)
inline

Dispose of a previously-created server.

This will immediately disconnect any pending client connections that had not yet been accepted, but will not disconnect any existing accepted connections (which can still be used and must be destroyed separately). Further attempts to make new connections to this server will fail on the client side.

Parameters
serverserver to destroy.
Thread safety:
You should not operate on the same server from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different servers at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateServer

◆ DestroyStreamSocket()

void SDL::DestroyStreamSocket ( StreamSocketRaw sock)
inline

Dispose of a previously-created stream socket.

This will immediately disconnect the other side of the connection, if necessary. Further attempts to read or write the socket on the remote end will fail.

This will abandon any data queued for sending that hasn't made it to the socket. If you need this data to arrive, you should wait for it to transmit before destroying the socket with GetStreamSocketPendingWrites() or WaitUntilStreamSocketDrained(). Any data that has arrived from the remote end of the connection that hasn't been read yet is lost.

Parameters
sockstream socket to destroy.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateClient
AcceptClient
GetStreamSocketPendingWrites
WaitUntilStreamSocketDrained

◆ FreeLocalAddresses()

void SDL::FreeLocalAddresses ( AddressRef * addresses)
inline

Free the results from GetLocalAddresses.

This will unref all addresses in the array and free the array itself.

Since addresses are reference counted, it is safe to keep any addresses you want from this array even after calling this function, as long as you called RefAddress() on them first.

It is safe to pass a nullptr in here, it will be ignored.

You most likely don't need to call this function directly, as the LocalAddressesArray type will call it for you when the array goes out of scope.

Parameters
addressesA pointer returned by GetLocalAddresses().
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ GetAddress()

Address SDL::StreamSocketBase::GetAddress ( )
inline

Get the remote address of a stream socket.

This reports the address of the remote side of a stream socket, which might still be pending connnection.

This adds a reference to the address; the caller must call UnrefAddress() when done with it.

Returns
the socket's remote address on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ GetAddressBytes()

const void * SDL::GetAddressBytes ( AddressRef address,
int * num_bytes )
inline

Get the protocol-level bytes of a network address from a resolved address.

This data is not human-readable, is protocol-specific, and might not even be in a specific byte order.

This is only useful for possibly hashing, to map a address to a specific player in a game, or possibly for handing to a system-level networking API (which is not recommended; an app does this at their own risk).

Do not store these bytes for future runs of the program; there is no promise the format won't change.

On return *num_bytes will hold the number of bytes provided with the address. Since the data is not nullptr-terminated, this is the only way to determine its size; as such, this parameter must not be nullptr.

Do not free or modify the returned data; it belongs to the Address that was queried, and is valid as long as the object lives. Either make sure the address has a reference as long as you need this or make a copy of the bytes.

This will return nullptr if resolution is still in progress, or if resolution failed. You can use GetAddressStatus() or WaitUntilResolved() to make sure resolution has successfully completed before calling this.

A human-readable version is available in GetAddressString() and isn't any less efficient to query than the raw bytes.

Parameters
addressThe Address to query.
num_byteson return, will be set to the number of bytes returned.
Returns
a pointer to bytes on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressString
GetAddressStatus
WaitUntilResolved

◆ GetAddressStatus()

Status SDL::GetAddressStatus ( AddressRef address)
inline

Check if an address is resolved, without blocking.

The Address objects returned by ResolveHostname take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

This function allows you to check the progress of that work without blocking.

Resolution can fail after some time (DNS server took awhile to reply that the hostname isn't recognized, etc), so be sure to check the result of this function instead of assuming it worked because it's non-zero!

Once an address is successfully resolved, it can be used to connect to the host represented by the address.

Parameters
addressThe Address to query.
Returns
SUCCESS if successfully resolved, FAILURE if resolution failed, WAITING if still resolving (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilResolved

◆ GetAddressString()

const char * SDL::GetAddressString ( AddressRef address)
inline

Get a human-readable string from a resolved address.

This returns a string that's "human-readable", in that it's probably a string of numbers and symbols, like "159.203.69.7" or "2604:a880:800:a1::71f:3001". It won't be the original hostname (like "icculus.org"), but it's suitable for writing to a log file, etc.

Do not free or modify the returned string; it belongs to the Address that was queried, and is valid as long as the object lives. Either make sure the address has a reference as long as you need this or make a copy of the string.

This will return nullptr if resolution is still in progress, or if resolution failed. You can use GetAddressStatus() or WaitUntilResolved() to make sure resolution has successfully completed before calling this.

Parameters
addressThe Address to query.
Returns
a string on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressStatus
WaitUntilResolved

◆ GetBytes()

const void * SDL::AddressBase::GetBytes ( int * num_bytes)
inline

Get the protocol-level bytes of a network address from a resolved address.

This data is not human-readable, is protocol-specific, and might not even be in a specific byte order.

This is only useful for possibly hashing, to map a address to a specific player in a game, or possibly for handing to a system-level networking API (which is not recommended; an app does this at their own risk).

Do not store these bytes for future runs of the program; there is no promise the format won't change.

On return *num_bytes will hold the number of bytes provided with the address. Since the data is not nullptr-terminated, this is the only way to determine its size; as such, this parameter must not be nullptr.

Do not free or modify the returned data; it belongs to the Address that was queried, and is valid as long as the object lives. Either make sure the address has a reference as long as you need this or make a copy of the bytes.

This will return nullptr if resolution is still in progress, or if resolution failed. You can use GetAddressStatus() or WaitUntilResolved() to make sure resolution has successfully completed before calling this.

A human-readable version is available in GetAddressString() and isn't any less efficient to query than the raw bytes.

Parameters
num_byteson return, will be set to the number of bytes returned.
Returns
a pointer to bytes on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressString
GetAddressStatus
WaitUntilResolved

◆ GetConnectionStatus() [1/2]

Status SDL::GetConnectionStatus ( StreamSocketRef sock)
inline

Check if a stream socket is connected, without blocking.

The StreamSocket objects returned by CreateClient take time to do negotiate a connection to a server, so it does so asynchronously instead of making your program wait an indefinite amount of time.

This function allows you to check the progress of that work without blocking.

Connection can fail after some time (server took a while to respond, and then rejected the connection), so be sure to check the result of this function instead of assuming it worked because it's non-zero!

Once a connection is successfully made, the stream socket can be used to send and receive data with the server.

Note that if the connection succeeds, but later the connection is dropped, this will still report the connection as successful, as it only deals with the initial asynchronous work of getting connected; you'll know the connection dropped later when your reads and writes report failures.

Parameters
sockthe stream socket to query.
Returns
SUCCESS if successfully connected, FAILURE if connection failed, WAITING if still connecting; if FAILURE, call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilConnected

◆ GetConnectionStatus() [2/2]

Status SDL::StreamSocketBase::GetConnectionStatus ( )
inline

Check if a stream socket is connected, without blocking.

The StreamSocket objects returned by CreateClient take time to do negotiate a connection to a server, so it does so asynchronously instead of making your program wait an indefinite amount of time.

This function allows you to check the progress of that work without blocking.

Connection can fail after some time (server took a while to respond, and then rejected the connection), so be sure to check the result of this function instead of assuming it worked because it's non-zero!

Once a connection is successfully made, the stream socket can be used to send and receive data with the server.

Note that if the connection succeeds, but later the connection is dropped, this will still report the connection as successful, as it only deals with the initial asynchronous work of getting connected; you'll know the connection dropped later when your reads and writes report failures.

Returns
SUCCESS if successfully connected, FAILURE if connection failed, WAITING if still connecting; if FAILURE, call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilConnected

◆ GetLocalAddresses()

LocalAddressesArray SDL::GetLocalAddresses ( )
inline

Obtain a list of local addresses on the system.

This returns addresses that you can theoretically bind a socket to, to accept connections from other machines at that address.

You almost never need this function; first, it's hard to tell what is a good address to bind to, without asking the user (who will likely find it equally hard to decide). Second, most machines will have lots of private addresses that are accessible on the same LAN, but not public ones that are accessible from the outside Internet.

Usually it's better to use CreateServer() or CreateDatagramSocket() with a nullptr address, to say "bind to all interfaces."

The array of addresses returned from this is guaranteed to be nullptr-terminated. You can also pass a pointer to an int, which will return the final count, not counting the nullptr at the end of the array.

Returns
A nullptr-terminated array of AddressRef, one for each bindable address on the system on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ GetPendingWrites()

int SDL::StreamSocketBase::GetPendingWrites ( )
inline

Query bytes still pending transmission on a stream socket.

If WriteToStreamSocket() couldn't send all its data immediately, it will queue it to be sent later. This function lets the app see how much of that queue is still pending to be sent.

The library will try to send more queued data before reporting what's left, but it will not block to do so.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Returns
number of bytes still pending transmission, -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket
WaitUntilStreamSocketDrained

◆ GetStatus()

Status SDL::AddressBase::GetStatus ( )
inline

Check if an address is resolved, without blocking.

The Address objects returned by ResolveHostname take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

This function allows you to check the progress of that work without blocking.

Resolution can fail after some time (DNS server took awhile to reply that the hostname isn't recognized, etc), so be sure to check the result of this function instead of assuming it worked because it's non-zero!

Once an address is successfully resolved, it can be used to connect to the host represented by the address.

Returns
SUCCESS if successfully resolved, FAILURE if resolution failed, WAITING if still resolving (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilResolved

◆ GetStreamSocketAddress()

Address SDL::GetStreamSocketAddress ( StreamSocketRef sock)
inline

Get the remote address of a stream socket.

This reports the address of the remote side of a stream socket, which might still be pending connnection.

This adds a reference to the address; the caller must call UnrefAddress() when done with it.

Parameters
sockthe stream socket to query.
Returns
the socket's remote address on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ GetStreamSocketPendingWrites()

int SDL::GetStreamSocketPendingWrites ( StreamSocketRef sock)
inline

Query bytes still pending transmission on a stream socket.

If WriteToStreamSocket() couldn't send all its data immediately, it will queue it to be sent later. This function lets the app see how much of that queue is still pending to be sent.

The library will try to send more queued data before reporting what's left, but it will not block to do so.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
sockthe stream socket to query.
Returns
number of bytes still pending transmission, -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket
WaitUntilStreamSocketDrained

◆ GetString()

const char * SDL::AddressBase::GetString ( )
inline

Get a human-readable string from a resolved address.

This returns a string that's "human-readable", in that it's probably a string of numbers and symbols, like "159.203.69.7" or "2604:a880:800:a1::71f:3001". It won't be the original hostname (like "icculus.org"), but it's suitable for writing to a log file, etc.

Do not free or modify the returned string; it belongs to the Address that was queried, and is valid as long as the object lives. Either make sure the address has a reference as long as you need this or make a copy of the string.

This will return nullptr if resolution is still in progress, or if resolution failed. You can use GetAddressStatus() or WaitUntilResolved() to make sure resolution has successfully completed before calling this.

Returns
a string on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressStatus
WaitUntilResolved

◆ operator<=>()

auto SDL::AddressBase::operator<=> ( const AddressBase & other) const
inline

Compares two addresses.

Returns std::strong_ordering::less if this address is less than the other, std::strong_ordering::greater if this address is greater than the other, and std::strong_ordering::equal if they are equal.

◆ operator==()

bool SDL::AddressBase::operator== ( const AddressBase & other) const
inline

Compares two addresses for equality.

Returns true if they are the same, false otherwise.

◆ ReadFrom()

int SDL::StreamSocketBase::ReadFrom ( void * buf,
int buflen )
inline

Receive bytes that a remote system sent to a stream socket.

Stream sockets are reliable, which means data sent over them will arrive in the order it was transmitted, and the system will retransmit data as necessary to ensure its delivery. Which is to say, short of catastrophic failure, data will arrive, possibly with severe delays. Also, "catastrophic failure" isn't an uncommon event.

(This is opposed to Datagram sockets, which send chunks of data that might arrive in any order, or not arrive at all, but you never wait for missing chunks to show up.)

Stream sockets are bidirectional; you can read and write from the same stream, and the other end of the connection can, too.

This function returns data that has arrived for the stream socket that hasn't been read yet. Data is provided in the order it was sent on the remote side. This function may return less data than requested, depending on what is available at the time, and also the app isn't required to read all available data at once.

This call never blocks; if no new data is available at the time of the call, it returns 0 immediately. The caller can try again later.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
bufa pointer to a buffer where received data will be collected.
buflenthe size of the buffer pointed to by buf, in bytes. This is the maximum that will be read from the stream socket.
Returns
number of bytes read from the stream socket (which can be less than buflen or zero if none available), -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket

◆ ReadFromStreamSocket()

int SDL::ReadFromStreamSocket ( StreamSocketRef sock,
void * buf,
int buflen )
inline

Receive bytes that a remote system sent to a stream socket.

Stream sockets are reliable, which means data sent over them will arrive in the order it was transmitted, and the system will retransmit data as necessary to ensure its delivery. Which is to say, short of catastrophic failure, data will arrive, possibly with severe delays. Also, "catastrophic failure" isn't an uncommon event.

(This is opposed to Datagram sockets, which send chunks of data that might arrive in any order, or not arrive at all, but you never wait for missing chunks to show up.)

Stream sockets are bidirectional; you can read and write from the same stream, and the other end of the connection can, too.

This function returns data that has arrived for the stream socket that hasn't been read yet. Data is provided in the order it was sent on the remote side. This function may return less data than requested, depending on what is available at the time, and also the app isn't required to read all available data at once.

This call never blocks; if no new data is available at the time of the call, it returns 0 immediately. The caller can try again later.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
sockthe stream socket to receive data from.
bufa pointer to a buffer where received data will be collected.
buflenthe size of the buffer pointed to by buf, in bytes. This is the maximum that will be read from the stream socket.
Returns
number of bytes read from the stream socket (which can be less than buflen or zero if none available), -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket

◆ Receive()

bool SDL::DatagramBase::Receive ( DatagramSocketRef sock)
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Parameters
sockthe datagram socket to send data through.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ ReceiveDatagram() [1/4]

Datagram SDL::DatagramSocketBase::ReceiveDatagram ( )
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Returns
a valid Datagram object if data sent or queued for transmission, nullptr on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ ReceiveDatagram() [2/4]

bool SDL::DatagramSocketBase::ReceiveDatagram ( Datagram & dgram)
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Parameters
dgrama reference to the datagram packet object.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ ReceiveDatagram() [3/4]

Datagram SDL::ReceiveDatagram ( DatagramSocketRef sock)
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Parameters
sockthe datagram socket to send data through.
Returns
a valid Datagram object if data sent or queued for transmission, nullptr on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ ReceiveDatagram() [4/4]

bool SDL::ReceiveDatagram ( DatagramSocketRef sock,
Datagram & dgram )
inline

Receive a new packet that a remote system sent to a datagram socket.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, so you'll never receive half a packet.

This call never blocks; if no new data is available at the time of the call, it returns true immediately. The caller can try again later.

On a successful call to this function, it returns true, even if no new packets are available, so you should check for a successful return and a non-nullptr value in *dgram to decide if a new packet is available.

You must pass received packets to DestroyDatagram when you are done with them. If you want to save the sender's address past this time, it is safe to call RefAddress() on the address and hold onto the pointer, so long as you call UnrefAddress() on it when you are done with it.

Since datagrams can arrive from any address or port on the network without prior warning, this information is available in the Datagram object that is provided by this function, and this is the only way to know who to reply to. Even if you aren't acting as a "server," packets can still arrive at your socket if someone sends one.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Parameters
sockthe datagram socket to send data through.
dgrama pointer to the datagram packet pointer.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
SendDatagram
DestroyDatagram

◆ RefAddress()

Address SDL::RefAddress ( AddressRef address)
inline

Add a reference to an Address.

Since several pieces of the library might share a single Address, including a background thread that's working on resolving, these objects are referenced counted. This allows everything that's using it to declare they still want it, and drop their reference to the address when they are done with it. The object's resources are freed when the last reference is dropped.

This function adds a reference to an Address, increasing its reference count by one.

The documentation will tell you when the app has to explicitly unref an address. For example, ResolveHostname() creates addresses that are already referenced, so the caller needs to unref it when done.

Generally you only have to explicit ref an address when you have different parts of your own app that will be sharing an address. In normal usage, you only have to unref things you've created once (like you might free() something), but you are free to add extra refs if it makes sense.

This returns the same address passed as a parameter, which makes it easy to ref and assign in one step:

myAddr = RefAddress(yourAddr);
Parameters
addressThe Address to add a reference to.
Returns
the same address that was passed as a parameter.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ ResolveHostname()

Address SDL::ResolveHostname ( StringParam host)
inline

Resolve a human-readable hostname.

SDL_net doesn't operate on human-readable hostnames (like www.libsdl.org but on computer-readable addresses. This function converts from one to the other. This process is known as "resolving" an address.

You can also use this to turn IP address strings (like "159.203.69.7") into Address objects.

Note that resolving an address is an asynchronous operation, since the library will need to ask a server on the internet to get the information it needs, and this can take time (and possibly fail later). This function will not block. It either returns nullptr (catastrophic failure) or an unresolved Address. Until the address resolves, it can't be used.

If you want to block until the resolution is finished, you can call WaitUntilResolved(). Otherwise, you can do a non-blocking check with GetAddressStatus().

When you are done with the returned Address, call UnrefAddress() to dispose of it. You need to do this even if resolution later fails asynchronously.

Parameters
hostThe hostname to resolve.
Returns
A new Address on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilResolved
GetAddressStatus
RefAddress
UnrefAddress

◆ SendDatagram() [1/2]

bool SDL::DatagramSocketBase::SendDatagram ( AddressRef address,
Uint16 port,
const void * buf,
int buflen )
inline

Send a new packet over a datagram socket to a remote system.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, as opposed to stream sockets, where individual bytes might trickle in as they attempt to reliably deliver a stream of data.

Datagram packets might arrive in a different order than you sent them, or they may just be lost while travelling across the network. You have to plan for this. As an added confusion, since SDL_net might send the same packet on multiple interfaces, you might get duplicate packets, possibly from different network addresses. You have to plan for this, too.

You can send to any address and port on the network, but there has to be a datagram socket waiting for the data on the other side for the packet not to be lost.

General wisdom is that you shouldn't send a packet larger than 1500 bytes over the Internet, as bad routers might fragment or lose larger ones, but this limit is not hardcoded into SDL_net and in good conditions you might be able to send significantly more.

This call never blocks; if it can't send the data immediately, the library will queue it for later transmission. There is no query to see what is still queued, as datagram transmission is unreliable, so you should never assume anything about queued data.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Sending to a nullptr address is treated as a request to broadcast a packet. Note that this will report failure immediately if the socket was not created with broadcast permission. Broadcast packets are (more or less) sent to every machine on the LAN, unconditionally.

WARNING: It is possible to build a game where everyone is playing on the same LAN, and every player is simply broadcasting packets. This is absolutely the wrong thing to do, however. Broadcast packets go to every device on the LAN, whether they want them or not. The game DOOM, in its heyday, was capable of bringing entire networks to their knees , as many players on the same network would all be broadcasting relentlessly.

In practice, broadcasting sparingly can be useful for certain functionality: a LAN-only client broadcasting a few packets to ask for available servers, and running servers replying directly to that client without broadcasting at all, is reasonable and safe. Once clients and servers have found each other, they can communicate directly without any broadcasting at all. For peer-to-peer games, once connection is established, it's better to either send unique packets to each known player, or use a multicasting (which works like broadcast, but only routes packets to devices that are explicitly listening for it).

With IPv6, which doesn't support broadcasts, broadcasting is faked with multicast to the all-nodes link-local multicast group, ff02::1, either on a specific interface or letting the OS choose the default. Other protocols might fake broadcast operations in similar ways in the future.

Parameters
addressthe Address object address. May be nullptr to broadcast.
portthe address port.
bufa pointer to the data to send as a single packet.
buflenthe size of the data to send, in bytes.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
ReceiveDatagram

◆ SendDatagram() [2/2]

bool SDL::SendDatagram ( DatagramSocketRef sock,
AddressRef address,
Uint16 port,
const void * buf,
int buflen )
inline

Send a new packet over a datagram socket to a remote system.

Datagram sockets send packets of data. They either arrive as complete packets or they don't arrive at all, as opposed to stream sockets, where individual bytes might trickle in as they attempt to reliably deliver a stream of data.

Datagram packets might arrive in a different order than you sent them, or they may just be lost while travelling across the network. You have to plan for this. As an added confusion, since SDL_net might send the same packet on multiple interfaces, you might get duplicate packets, possibly from different network addresses. You have to plan for this, too.

You can send to any address and port on the network, but there has to be a datagram socket waiting for the data on the other side for the packet not to be lost.

General wisdom is that you shouldn't send a packet larger than 1500 bytes over the Internet, as bad routers might fragment or lose larger ones, but this limit is not hardcoded into SDL_net and in good conditions you might be able to send significantly more.

This call never blocks; if it can't send the data immediately, the library will queue it for later transmission. There is no query to see what is still queued, as datagram transmission is unreliable, so you should never assume anything about queued data.

If there's a fatal error, this function will return false. Datagram sockets generally won't report failures, because there is no state like a "connection" to fail at this level, but may report failure for unrecoverable system-level conditions; once a datagram socket fails, you should assume it is no longer usable and should destroy it with SDL_DestroyDatagramSocket().

Sending to a nullptr address is treated as a request to broadcast a packet. Note that this will report failure immediately if the socket was not created with broadcast permission. Broadcast packets are (more or less) sent to every machine on the LAN, unconditionally.

WARNING: It is possible to build a game where everyone is playing on the same LAN, and every player is simply broadcasting packets. This is absolutely the wrong thing to do, however. Broadcast packets go to every device on the LAN, whether they want them or not. The game DOOM, in its heyday, was capable of bringing entire networks to their knees , as many players on the same network would all be broadcasting relentlessly.

In practice, broadcasting sparingly can be useful for certain functionality: a LAN-only client broadcasting a few packets to ask for available servers, and running servers replying directly to that client without broadcasting at all, is reasonable and safe. Once clients and servers have found each other, they can communicate directly without any broadcasting at all. For peer-to-peer games, once connection is established, it's better to either send unique packets to each known player, or use a multicasting (which works like broadcast, but only routes packets to devices that are explicitly listening for it).

With IPv6, which doesn't support broadcasts, broadcasting is faked with multicast to the all-nodes link-local multicast group, ff02::1, either on a specific interface or letting the OS choose the default. Other protocols might fake broadcast operations in similar ways in the future.

Parameters
sockthe datagram socket to send data through.
addressthe Address object address. May be nullptr to broadcast.
portthe address port.
bufa pointer to the data to send as a single packet.
buflenthe size of the data to send, in bytes.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
ReceiveDatagram

◆ Server()

SDL::Server::Server ( AddressRef addr,
Uint16 port,
PropertiesRef props )
inline

Create a server, which listens for connections to accept.

An app that initiates connection to a remote computer is called a "client," and the thing the client connects to is called a "server."

Servers listen for and accept connections from clients, which spawns a new stream socket on the server's end, which it can then send/receive data on.

Use this function to create a server that will accept connections from other systems.

This function does not block, and is not asynchronous, as the system can decide immediately if it can create a server or not. If this returns success, you can immediately start accepting connections.

You can specify an address to listen for connections on; this address must be local to the system, and probably one returned by GetLocalAddresses(), but almost always you just want to specify nullptr here, to listen on any address available to the app.

After creating a server, you get stream sockets to talk to incoming client connections by calling AcceptClient().

Stream sockets don't employ any protocol (above the TCP level), so they can accept connections from clients that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

The caller may supply properties to customize behavior. This is optional, and a value of zero for props will request defaults for all properties.

These are the supported properties:

  • prop.Server.REUSEADDR_BOOLEAN: true if the server should be created even if a previous server has recently used this address. For various reasons, networks prefer that there be some delay between apps reusing the same address, but this can be problematic when iterating quickly, for software development purposes or just restarting a crashed service. This property defaults to true (although it should be noted that, at the operating system level, this defaults to false!). If this property is false and the OS feels that not enough time has elapsed, server creation will fail and this function will report an error.
Parameters
addrthe local address to listen for connections on, or nullptr.
portthe port on the local address to listen for connections on.
propsproperties of the new server. Specify zero for defaults.
Postcondition
a new Server on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
GetLocalAddresses
AcceptClient
DestroyServer

◆ SimulateAddressResolutionLoss()

void SDL::SimulateAddressResolutionLoss ( int percent_loss)
inline

Enable simulated address resolution failures.

Often times, testing a networked app on your development machine–which might have a wired connection to a fast, reliable network service–won't expose bugs that happen when networks intermittently fail in the real world, when the wifi is flakey and firewalls get in the way.

This function allows you to tell the library to pretend that some percentage of address resolutions will fail.

The higher the percentage, the more resolutions will fail and/or take longer for resolution to complete.

Setting this to zero (the default) will disable the simulation. Setting to 100 means everything fails unconditionally. At what percent the system merely borders on unusable is left as an exercise to the app developer.

This is intended for debugging purposes, to simulate real-world conditions that are various degrees of terrible. You probably should not call this in production code, where you'll likely see real failures anyhow.

Parameters
percent_lossA number between 0 and 100. Higher means more failures. Zero to disable.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ SimulateDatagramPacketLoss() [1/2]

void SDL::DatagramSocketBase::SimulateDatagramPacketLoss ( int percent_loss)
inline

Enable simulated datagram socket failures.

Often times, testing a networked app on your development machine–which might have a wired connection to a fast, reliable network service–won't expose bugs that happen when networks intermittently fail in the real world, when the wifi is flakey and firewalls get in the way.

This function allows you to tell the library to pretend that some percentage of datagram socket data transmission will fail.

The library will randomly lose packets (both incoming and outgoing) at an average matching percent_loss. Setting this to zero (the default) will disable the simulation. Setting to 100 means everything fails unconditionally and no further data will get through. At what percent the system merely borders on unusable is left as an exercise to the app developer.

This is intended for debugging purposes, to simulate real-world conditions that are various degrees of terrible. You probably should not call this in production code, where you'll likely see real failures anyhow.

Parameters
percent_lossA number between 0 and 100. Higher means more failures. Zero to disable.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ SimulateDatagramPacketLoss() [2/2]

void SDL::SimulateDatagramPacketLoss ( DatagramSocketRef sock,
int percent_loss )
inline

Enable simulated datagram socket failures.

Often times, testing a networked app on your development machine–which might have a wired connection to a fast, reliable network service–won't expose bugs that happen when networks intermittently fail in the real world, when the wifi is flakey and firewalls get in the way.

This function allows you to tell the library to pretend that some percentage of datagram socket data transmission will fail.

The library will randomly lose packets (both incoming and outgoing) at an average matching percent_loss. Setting this to zero (the default) will disable the simulation. Setting to 100 means everything fails unconditionally and no further data will get through. At what percent the system merely borders on unusable is left as an exercise to the app developer.

This is intended for debugging purposes, to simulate real-world conditions that are various degrees of terrible. You probably should not call this in production code, where you'll likely see real failures anyhow.

Parameters
sockThe socket to set a failure rate on.
percent_lossA number between 0 and 100. Higher means more failures. Zero to disable.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ SimulateStreamPacketLoss() [1/2]

void SDL::SimulateStreamPacketLoss ( StreamSocketRef sock,
int percent_loss )
inline

Enable simulated stream socket failures.

Often times, testing a networked app on your development machine–which might have a wired connection to a fast, reliable network service–won't expose bugs that happen when networks intermittently fail in the real world, when the wifi is flakey and firewalls get in the way.

This function allows you to tell the library to pretend that some percentage of stream socket data transmission will fail.

Since stream sockets are reliable, failure in this case pretends that packets are getting lost on the network, making the stream retransmit to deal with it. To simulate this, the library will introduce some amount of delay before it sends or receives data on the socket. The higher the percentage, the more delay is introduced for bytes to make their way to their final destination. The library may also decide to drop connections at random, to simulate disasterous network conditions.

Setting this to zero (the default) will disable the simulation. Setting to 100 means everything fails unconditionally and no further data will get through (and perhaps your sockets eventually fail). At what percent the system merely borders on unusable is left as an exercise to the app developer.

This is intended for debugging purposes, to simulate real-world conditions that are various degrees of terrible. You probably should not call this in production code, where you'll likely see real failures anyhow.

Parameters
sockThe socket to set a failure rate on.
percent_lossA number between 0 and 100. Higher means more failures. Zero to disable.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ SimulateStreamPacketLoss() [2/2]

void SDL::StreamSocketBase::SimulateStreamPacketLoss ( int percent_loss)
inline

Enable simulated stream socket failures.

Often times, testing a networked app on your development machine–which might have a wired connection to a fast, reliable network service–won't expose bugs that happen when networks intermittently fail in the real world, when the wifi is flakey and firewalls get in the way.

This function allows you to tell the library to pretend that some percentage of stream socket data transmission will fail.

Since stream sockets are reliable, failure in this case pretends that packets are getting lost on the network, making the stream retransmit to deal with it. To simulate this, the library will introduce some amount of delay before it sends or receives data on the socket. The higher the percentage, the more delay is introduced for bytes to make their way to their final destination. The library may also decide to drop connections at random, to simulate disasterous network conditions.

Setting this to zero (the default) will disable the simulation. Setting to 100 means everything fails unconditionally and no further data will get through (and perhaps your sockets eventually fail). At what percent the system merely borders on unusable is left as an exercise to the app developer.

This is intended for debugging purposes, to simulate real-world conditions that are various degrees of terrible. You probably should not call this in production code, where you'll likely see real failures anyhow.

Parameters
percent_lossA number between 0 and 100. Higher means more failures. Zero to disable.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ StreamSocket()

SDL::StreamSocket::StreamSocket ( AddressRef address,
Uint16 port,
PropertiesRef props )
inline

Begin connecting a socket as a client to a remote server.

Each StreamSocket represents a single connection between systems. Usually, a client app will have one connection to a server app on a different computer, and the server app might have many connections from different clients. Each of these connections communicate over a separate stream socket.

Connecting is an asynchronous operation; this function does not block, and will return before the connection is complete. One has to then use WaitUntilConnected() or GetConnectionStatus() to see when the operation has completed, and if it was successful.

Once connected, you can read and write data to the returned socket. Stream sockets are a mode of reliable transmission, which means data will be received as a stream of bytes in the order you sent it. If there are problems in transmission, the system will deal with protocol negotiation and retransmission as necessary, transparent to your app, but this means until data is available in the order sent, the remote side will not get any new data. This is the tradeoff vs datagram sockets, where data can arrive in any order, or not arrive at all, without waiting, but the sender will not know.

Stream sockets don't employ any protocol (above the TCP level), so they can connect to servers that aren't using SDL_net, but if you want to speak any protocol beyond an abritrary stream of bytes, such as HTTP, you'll have to implement that yourself on top of the stream socket.

This function will fail if address is not finished resolving.

When you are done with this connection (whether it failed to connect or not), you must dispose of it with DestroyStreamSocket().

Unlike BSD sockets or WinSock, you specify the port as a normal integer; you do not have to byteswap it into "network order," as the library will handle that for you.

There are currently no extra properties for creating a client, so props should be zero. A future revision of SDL_net may add additional (optional) properties.

Parameters
addressthe address of the remote server to connect to.
portthe port on the remote server to connect to.
propsproperties of the new client. Specify zero for defaults.
Postcondition
pending connection on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.
See also
WaitUntilConnected
GetConnectionStatus
DestroyStreamSocket

◆ Unref()

void SDL::AddressBase::Unref ( )
inline

Drop a reference to an Address.

Since several pieces of the library might share a single Address, including a background thread that's working on resolving, these objects are referenced counted. This allows everything that's using it to declare they still want it, and drop their reference to the address when they are done with it. The object's resources are freed when the last reference is dropped.

This function drops a reference to an Address, decreasing its reference count by one.

The documentation will tell you when the app has to explicitly unref an address. For example, ResolveHostname() creates addresses that are already referenced, so the caller needs to unref it when done.

Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ UnrefAddress()

void SDL::UnrefAddress ( AddressRaw address)
inline

Drop a reference to an Address.

Since several pieces of the library might share a single Address, including a background thread that's working on resolving, these objects are referenced counted. This allows everything that's using it to declare they still want it, and drop their reference to the address when they are done with it. The object's resources are freed when the last reference is dropped.

This function drops a reference to an Address, decreasing its reference count by one.

The documentation will tell you when the app has to explicitly unref an address. For example, ResolveHostname() creates addresses that are already referenced, so the caller needs to unref it when done.

Parameters
addressThe Address to drop a reference to.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL_net 3.0.0.

◆ WaitUntilConnected() [1/2]

Status SDL::StreamSocketBase::WaitUntilConnected ( Sint32 timeout)
inline

Block until a stream socket has connected to a server.

The StreamSocket objects returned by CreateClient take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

However, if you want your program to sleep until the connection is complete, you can call this function.

This function takes a timeout value, represented in milliseconds, of how long to wait for resolution to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetConnectionStatus).

Connections can fail after some time (server took awhile to respond at all, and then refused the connection outright), so be sure to check the result of this function instead of assuming it worked!

Once a connection is successfully made, the socket may read data from, or write data to, the connected server.

If you don't want your program to block, you can call GetConnectionStatus() from time to time until you get a non-zero result.

Parameters
timeoutNumber of milliseconds to wait for resolution to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
SUCCESS if successfully connected, FAILURE if connection failed, WAITING if still connecting (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different socket at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
GetConnectionStatus

◆ WaitUntilConnected() [2/2]

Status SDL::WaitUntilConnected ( StreamSocketRef sock,
Sint32 timeout )
inline

Block until a stream socket has connected to a server.

The StreamSocket objects returned by CreateClient take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

However, if you want your program to sleep until the connection is complete, you can call this function.

This function takes a timeout value, represented in milliseconds, of how long to wait for resolution to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetConnectionStatus).

Connections can fail after some time (server took awhile to respond at all, and then refused the connection outright), so be sure to check the result of this function instead of assuming it worked!

Once a connection is successfully made, the socket may read data from, or write data to, the connected server.

If you don't want your program to block, you can call GetConnectionStatus() from time to time until you get a non-zero result.

Parameters
sockThe StreamSocket object to wait on.
timeoutNumber of milliseconds to wait for resolution to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
SUCCESS if successfully connected, FAILURE if connection failed, WAITING if still connecting (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different socket at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
GetConnectionStatus

◆ WaitUntilDrained()

int SDL::StreamSocketBase::WaitUntilDrained ( Sint32 timeout)
inline

Block until all of a stream socket's pending data is sent.

If WriteToStreamSocket() couldn't send all its data immediately, it will queue it to be sent later. This function lets the app sleep until all the data is transmitted.

This function takes a timeout value, represented in milliseconds, of how long to wait for transmission to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetStreamSocketPendingWrites).

If you don't want your program to block, you can call GetStreamSocketPendingWrites from time to time until you get a result <= 0.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
timeoutNumber of milliseconds to wait for draining to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
number of bytes still pending transmission, -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket
GetStreamSocketPendingWrites

◆ WaitUntilInputAvailable()

int SDL::WaitUntilInputAvailable ( void ** vsockets,
int numsockets,
Sint32 timeout )
inline

Block on multiple sockets until at least one has data available.

This is a complex function that most apps won't need, but it could be used to implement a more efficient server or i/o thread in some cases.

This allows you to give it a list of objects and wait for new input to become available on any of them. The calling thread is put to sleep until such a time.

The following things can be specified in the vsockets array, cast to void *:

  • Server (reports new input when a connection is ready to be accepted with AcceptClient())
  • StreamSocket (reports new input when the remote end has sent more bytes of data to be read with ReadFromStreamSocket, or if the socket finished making its initial connection).
  • DatagramSocket (reports new input when a new packet arrives that can be read with ReceiveDatagram).

This function takes a timeout value, represented in milliseconds, of how long to wait for resolution to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately.

This returns the number of items that have new input, but it does not tell you which ones; since access to them is non-blocking, you can just try to read from each of them and see which are ready. If nothing is ready and the timeout is reached, this returns zero. On error, this returns -1.

Parameters
vsocketsan array of pointers to various objects that can be waited on, each cast to a void pointer.
numsocketsthe number of pointers in the vsockets array.
timeoutNumber of milliseconds to wait for new input to become available. -1 to wait indefinitely, 0 to check once without waiting.
Returns
the number of items that have new input, or -1 on error.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
CreateDatagramSocket
SendDatagram
ReceiveDatagram

◆ WaitUntilResolved() [1/2]

Status SDL::AddressBase::WaitUntilResolved ( Sint32 timeout)
inline

Block until an address is resolved.

The Address objects returned by ResolveHostname take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

However, if you want your program to sleep until the address resolution is complete, you can call this function.

This function takes a timeout value, represented in milliseconds, of how long to wait for resolution to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetAddressStatus).

Resolution can fail after some time (DNS server took awhile to reply that the hostname isn't recognized, etc), so be sure to check the result of this function instead of assuming it worked!

Once an address is successfully resolved, it can be used to connect to the host represented by the address.

If you don't want your program to block, you can call GetAddressStatus from time to time until you get a non-zero result.

Parameters
timeoutNumber of milliseconds to wait for resolution to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
SUCCESS if successfully resolved, FAILURE if resolution failed, WAITING if still resolving (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
It is safe to call this function from any thread, and several threads can block on the same address simultaneously.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressStatus

◆ WaitUntilResolved() [2/2]

Status SDL::WaitUntilResolved ( AddressRef address,
Sint32 timeout )
inline

Block until an address is resolved.

The Address objects returned by ResolveHostname take time to do their work, so it does so asynchronously instead of making your program wait an indefinite amount of time.

However, if you want your program to sleep until the address resolution is complete, you can call this function.

This function takes a timeout value, represented in milliseconds, of how long to wait for resolution to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetAddressStatus).

Resolution can fail after some time (DNS server took awhile to reply that the hostname isn't recognized, etc), so be sure to check the result of this function instead of assuming it worked!

Once an address is successfully resolved, it can be used to connect to the host represented by the address.

If you don't want your program to block, you can call GetAddressStatus from time to time until you get a non-zero result.

Parameters
addressThe Address object to wait on.
timeoutNumber of milliseconds to wait for resolution to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
SUCCESS if successfully resolved, FAILURE if resolution failed, WAITING if still resolving (this function timed out without resolution); if FAILURE, call GetError() for details.
Thread safety:
It is safe to call this function from any thread, and several threads can block on the same address simultaneously.
Since
This function is available since SDL_net 3.0.0.
See also
GetAddressStatus

◆ WaitUntilStreamSocketDrained()

int SDL::WaitUntilStreamSocketDrained ( StreamSocketRef sock,
Sint32 timeout )
inline

Block until all of a stream socket's pending data is sent.

If WriteToStreamSocket() couldn't send all its data immediately, it will queue it to be sent later. This function lets the app sleep until all the data is transmitted.

This function takes a timeout value, represented in milliseconds, of how long to wait for transmission to complete. Specifying a timeout of -1 instructs the library to wait indefinitely, and a timeout of 0 just checks the current status and returns immediately (and is functionally equivalent to calling GetStreamSocketPendingWrites).

If you don't want your program to block, you can call GetStreamSocketPendingWrites from time to time until you get a result <= 0.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning -1. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
sockthe stream socket to wait on.
timeoutNumber of milliseconds to wait for draining to complete. -1 to wait indefinitely, 0 to check once without waiting.
Returns
number of bytes still pending transmission, -1 on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
WriteToStreamSocket
GetStreamSocketPendingWrites

◆ WriteTo()

bool SDL::StreamSocketBase::WriteTo ( const void * buf,
int buflen )
inline

Send bytes over a stream socket to a remote system.

Stream sockets are reliable, which means data sent over them will arrive in the order it was transmitted, and the system will retransmit data as necessary to ensure its delivery. Which is to say, short of catastrophic failure, data will arrive, possibly with severe delays. Also, "catastrophic failure" isn't an uncommon event.

(This is opposed to Datagram sockets, which send chunks of data that might arrive in any order, or not arrive at all, but you never wait for missing chunks to show up.)

Stream sockets are bidirectional; you can read and write from the same stream, and the other end of the connection can, too.

This call never blocks; if it can't send the data immediately, the library will queue it for later transmission. You can use GetStreamSocketPendingWrites() to see how much is still queued for later transmission, or WaitUntilStreamSocketDrained() to block until all pending data has been sent.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning false. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
bufa pointer to the data to send.
buflenthe size of the data to send, in bytes.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
GetStreamSocketPendingWrites
WaitUntilStreamSocketDrained
ReadFromStreamSocket

◆ WriteToStreamSocket()

bool SDL::WriteToStreamSocket ( StreamSocketRef sock,
const void * buf,
int buflen )
inline

Send bytes over a stream socket to a remote system.

Stream sockets are reliable, which means data sent over them will arrive in the order it was transmitted, and the system will retransmit data as necessary to ensure its delivery. Which is to say, short of catastrophic failure, data will arrive, possibly with severe delays. Also, "catastrophic failure" isn't an uncommon event.

(This is opposed to Datagram sockets, which send chunks of data that might arrive in any order, or not arrive at all, but you never wait for missing chunks to show up.)

Stream sockets are bidirectional; you can read and write from the same stream, and the other end of the connection can, too.

This call never blocks; if it can't send the data immediately, the library will queue it for later transmission. You can use GetStreamSocketPendingWrites() to see how much is still queued for later transmission, or WaitUntilStreamSocketDrained() to block until all pending data has been sent.

If the connection has failed (remote side dropped us, or one of a million other networking failures occurred), this function will report failure by returning false. Stream sockets only report failure for unrecoverable conditions; once a stream socket fails, you should assume it is no longer usable and should destroy it with DestroyStreamSocket().

Parameters
sockthe stream socket to send data through.
bufa pointer to the data to send.
buflenthe size of the data to send, in bytes.
Returns
true if data sent or queued for transmission, false on failure; call GetError() for details.
Thread safety:
You should not operate on the same socket from multiple threads at the same time without supplying a serialization mechanism. However, different threads may access different sockets at the same time without problems.
Since
This function is available since SDL_net 3.0.0.
See also
GetStreamSocketPendingWrites
WaitUntilStreamSocketDrained
ReadFromStreamSocket

Variable Documentation

◆ FAILURE

Status SDL::FAILURE
constexpr
Initial value:
=
NET_FAILURE

Async operation complete, result was failure.

◆ SUCCESS

Status SDL::SUCCESS
constexpr
Initial value:
=
NET_SUCCESS

Async operation complete, result was success.