net topic
CategorySDLNet
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. It's 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 NET_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 NET_Address to talk over the network. If you need to convert a hostname (such as "google.com" or "libsdl.org") into a NET_Address, you can call NET_ResolveHostname(), which will do the appropriate DNS queries on a background thread. Once these are ready, you can use the NET_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 NET_Address you resolved with NET_CreateClient(). Once the connection is established (a non-blocking operation), you'll have a NET_StreamSocket object that can send and receive data over the connection, using NET_WriteToStreamSocket() and NET_ReadFromStreamSocket().
To instead be a server, that clients connect to, call NET_CreateServer() to get a NET_Server object. All a NET_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. NET_CreateDatagramSocket() is used to prepare for datagram communication, then NET_SendDatagram() and NET_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:
- NET_WaitUntilConnected
- NET_WaitUntilInputAvailable
- NET_WaitUntilResolved
- NET_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:
- NET_SimulateAddressResolutionLoss
- NET_SimulateStreamPacketLoss
- NET_SimulateDatagramPacketLoss
Functions
-
netAcceptClient(
Pointer< netNetServer> server, Pointer<Pointer< clientStream) → boolNetStreamSocket> > - Create a stream socket for the next pending client connection.
-
netCompareAddresses(
Pointer< netNetAddress> a, Pointer<NetAddress> b) → int - Compare two NET_Address objects.
-
netCreateClient(
Pointer< netNetAddress> address, int port) → Pointer<NetStreamSocket> - Begin connecting a socket as a client to a remote server.
-
netCreateDatagramSocket(
Pointer< netNetAddress> addr, int port) → Pointer<NetDatagramSocket> - Create and bind a new datagram socket.
-
netCreateServer(
Pointer< netNetAddress> addr, int port) → Pointer<NetServer> - Create a server, which listens for connections to accept.
-
netDestroyDatagram(
Pointer< netNetDatagram> dgram) → void - Dispose of a datagram packet previously received.
-
netDestroyDatagramSocket(
Pointer< netNetDatagramSocket> sock) → void - Dispose of a previously-created datagram socket.
-
netDestroyServer(
Pointer< netNetServer> server) → void - Dispose of a previously-created server.
-
netDestroyStreamSocket(
Pointer< netNetStreamSocket> sock) → void - Dispose of a previously-created stream socket.
-
netFreeLocalAddresses(
Pointer< netPointer< addresses) → voidNetAddress> > - Free the results from NET_GetLocalAddresses.
-
netGetAddressStatus(
Pointer< netNetAddress> address) → int - Check if an address is resolved, without blocking.
-
netGetAddressString(
Pointer< netNetAddress> address) → String? - Get a human-readable string from a resolved address.
-
netGetConnectionStatus(
Pointer< netNetStreamSocket> sock) → int - Check if a stream socket is connected, without blocking.
-
netGetLocalAddresses(
Pointer< netInt32> numAddresses) → Pointer<Pointer< NetAddress> > - Obtain a list of local addresses on the system.
-
netGetStreamSocketAddress(
Pointer< netNetStreamSocket> sock) → Pointer<NetAddress> - Get the remote address of a stream socket.
-
netGetStreamSocketPendingWrites(
Pointer< netNetStreamSocket> sock) → int - Query bytes still pending transmission on a stream socket.
-
netInit(
) → bool net - Initialize the SDL_net library.
-
netQuit(
) → void net - Deinitialize the SDL_net library.
-
netReadFromStreamSocket(
Pointer< netNetStreamSocket> sock, Pointer<NativeType> buf, int buflen) → int - Receive bytes that a remote system sent to a stream socket.
-
netReceiveDatagram(
Pointer< netNetDatagramSocket> sock, Pointer<Pointer< dgram) → boolNetDatagram> > - Receive a new packet that a remote system sent to a datagram socket.
-
netRefAddress(
Pointer< netNetAddress> address) → Pointer<NetAddress> - Add a reference to an NET_Address.
-
netResolveHostname(
String? host) → Pointer< netNetAddress> - Resolve a human-readable hostname.
-
netSendDatagram(
Pointer< netNetDatagramSocket> sock, Pointer<NetAddress> address, int port, Pointer<NativeType> buf, int buflen) → bool - Send a new packet over a datagram socket to a remote system.
-
netSimulateAddressResolutionLoss(
int percentLoss) → void net - Enable simulated address resolution failures.
-
netSimulateDatagramPacketLoss(
Pointer< netNetDatagramSocket> sock, int percentLoss) → void - Enable simulated datagram socket failures.
-
netSimulateStreamPacketLoss(
Pointer< netNetStreamSocket> sock, int percentLoss) → void - Enable simulated stream socket failures.
-
netUnrefAddress(
Pointer< netNetAddress> address) → void - Drop a reference to an NET_Address.
-
netVersion(
) → int net - This function gets the version of the dynamically linked SDL_net library.
-
netWaitUntilConnected(
Pointer< netNetStreamSocket> sock, int timeout) → int - Block until a stream socket has connected to a server.
-
netWaitUntilInputAvailable(
Pointer< netPointer< vsockets, int numsockets, int timeout) → intNativeType> > - Block on multiple sockets until at least one has data available.
-
netWaitUntilResolved(
Pointer< netNetAddress> address, int timeout) → int - Block until an address is resolved.
-
netWaitUntilStreamSocketDrained(
Pointer< netNetStreamSocket> sock, int timeout) → int - Block until all of a stream socket's pending data is sent.
-
netWriteToStreamSocket(
Pointer< netNetStreamSocket> sock, Pointer<NativeType> buf, int buflen) → bool - Send bytes over a stream socket to a remote system.