![]() |
CRM64Pro GDK v0.16.0
A free cross-platform game development kit built on top of SDL 3.0
|
Network TCP/IP interface providing a client/server architecture [v26.03.0].
The Network TCP/IP interface provides a complete TCP client/server communication layer built on top of SDL3_net (SDL_net 3.0.0). It manages connection establishment, login handshake, packet transmission, validation, optional payload protection, queued delivery and runtime statistics through a unified API designed for both stand-alone server deployments and mixed local client+server setups in the same process.
| Max clients | Up to 8 simultaneous connections |
|---|---|
| Login system | Optional password authentication (can be enabled or disabled) |
| Deployment | Stand-alone server process or shared with a client instance |
| Backend | SDL3_net (SDL_net 3.0.0) with stream sockets |
| Payload limit | Up to 4 MB per DataNet payload |
NetTCP uses TCP as a reliable byte stream, but the application never works directly with raw stream bytes. Instead, traffic is wrapped into internal DataNet packets that contain:
The receive side reconstructs each full packet from the stream, validates it, optionally decrypts the payload and then either handles it internally or places it into the application receive queue.
The login flow is challenge-based:
This approach allows per-session cryptographic state to be derived for each connection instead of relying only on a static shared secret.
The server supports two working modes depending on how client actions are validated:
Non-authoritative mode
| Data processing | User packets are forwarded without gameplay validation |
|---|---|
| Client rights | Each client has full rights for performing any action |
| Client behavior | "I do my action and report it to others" |
| Use case | Games where clients do not compete for unique items or actions |
Authoritative mode
| Data processing | Query packets are evaluated by the server callback and can be accepted or denied |
|---|---|
| Client rights | Clients cannot perform actions until accepted by the server callback |
| Client behavior | "Can I do this action?" → wait for server response → proceed if accepted |
| Use case | Games where clients compete for unique items or actions |
Internal/system packets such as login, disconnect, ping and information updates are handled by the protocol regardless of the selected gameplay validation mode.
The current implementation provides several transport protections with distinct roles:
| xxHash3 | Fast packet integrity check using the full 64-bit xxHash3 result |
|---|---|
| PCG sequencer | Applied to user packets to detect out-of-sync or otherwise unexpected packet streams |
| AES-CTR | Optional payload encryption for post-login user DataNets using login-derived session state and per-packet sequence values |
| Packet obfuscation | Legacy packet-wide XOR layer. Useful as lightweight obfuscation but not a replacement for real session encryption |
In practice, this means NetTCP combines session setup, packet integrity checks, ordered user traffic and optional encrypted user payload transport instead of relying on a single monolithic "encrypted/not encrypted" mode.
Outgoing application packets are copied into per-side or per-client queues and later flushed by the owner thread. This allows reduced contention on socket access, queue statistics, peak tracking and graceful handling of temporary backpressure.
When pending socket writes for user traffic exceed the configured high watermark, NetTCP temporarily pauses user-packet flushing until the backlog falls below the low watermark. This soft-brake mechanism avoids unbounded packet buildup while keeping the API non-blocking.
The module tracks a broad set of runtime diagnostics, including:
The info() report prints live telemetry for the local NetTCP client and/or server instance. The example below shows the full report format and the table describes each field once, indicating whether it appears on the client, the server or both sides.
[Network Interface] Info: | - NetTCP Client v26.03.0: | Uptime 143.34 s | Features: none | Simulated delay 0 ms | RX: | Queued DataNets: Current 0 - Peak 102/512 - Dropped 0 | Buffered data: Queue 0 B (peak 3 MB) - Handed to app 0 B - Current DataNet 0 B (peak 3 MB) | DataNets: System 148 - User 1428168 | Data volume: Total 7.91 GB - Throughput 56.49 MB/s | Average DataNet size: System 25 B - User 5.81 KB | Errors: Bad header 0 - Bad data 0 - Hash 0 - Sequencer 0 | TX: | Queued DataNets: Current 0 - Peak 1/512 | TX throttle: High 256.00 KB - Low 128.00 KB | Buffered data: Queue 0 B (peak 0 B) - Socket pending 0 B - Total pending 0 B - Current DataNet 0 B (peak 24 B) | DataNets: System 145 - User 0 | Data volume: Total 3.42 KB - Throughput 24 B/s | Average DataNet size: System 24 B - User 0 B | Errors: Throttled 0 - Limit 0 - Send fail 0 | | - NetTCP Server v26.03.0: | Uptime 143.38 s | Features: none | Connected clients: 2 | Latency: Avg 2 ms - Max 2 ms | RX: | Buffered data: Current DataNet 0 B (peak 3 MB) | DataNets: System 288 - User 1428168 | Data volume: Total 7.91 GB - Throughput 56.47 MB/s | Average DataNet size: System 24 B - User 5.81 KB | Errors: Bad header 0 - Bad data 0 - Hash 0 - Sequencer 0 | TX: | Queued DataNets: Current avg 0 - Current max 0 - Peak max 1/512 | TX throttle: High 256.00 KB - Low 128.00 KB | Buffered data: Queue avg 0 B - Queue max 0 B - Queue peak 3 MB - Current DataNet 0 B (peak 3 MB) | DataNets: System 292 - User 2856336 | Data volume: Total 15.81 GB - Throughput 112.95 MB/s | Average DataNet size: System 25 B - User 5.81 KB | Errors: Throttled 0 - Limit 0 - Send fail 0
| Field | Scope | Meaning |
|---|---|---|
| Uptime | Both | Time elapsed since the local NetTCP client or server instance started running. |
| Features | Both | Feature state reported for that side. On the client this shows negotiated session features; on the server it shows the locally configured server feature flags. |
| Simulated delay | Client | Artificial client-side delay in milliseconds used for testing latency-sensitive code paths. |
| Connected clients | Server | Number of clients currently connected to the local server. |
| Latency: Avg / Max | Server | Aggregate latency summary across currently connected clients. It is useful as a quick health indicator, not a substitute for per-client inspection. |
| RX > Queued DataNets | Client | Receive queue population. Current is the number of packets waiting for the application, Peak is the highest observed queue usage and Dropped counts packets discarded because the queue was full. |
| RX > Buffered data | Both | Byte usage in the receive path. On the client, Queue is the queued byte count, peak is its high-water mark and Handed to app counts bytes delivered through receiveData() but not yet released with freeData(). On both client and server, Current DataNet is the size of the packet currently being assembled or processed and peak is the largest packet seen in the RX path. |
| RX > DataNets | Both | Count of received packets split into System protocol packets and User application packets. |
| RX > Data volume | Both | Total is the number of received bytes since startup, including headers and payloads. Throughput is the average receive rate since startup shown in human-readable form. |
| RX > Average DataNet size | Both | Average size of received System packets and received User packets. |
| RX > Errors | Both | Bad header counts malformed, incomplete or timed-out packet headers. Bad data counts malformed, incomplete or timed-out payloads. Hash counts integrity mismatches. Sequencer counts user packets rejected because the expected PCG sequence value did not match. |
| TX > Queued DataNets | Client, Server | Transmit queue population. On the client, Current is the number of outbound packets currently queued and Peak is the highest observed queue usage. On the server, Current avg is the average queued outbound packet count across connected clients, Current max is the highest current queue population among them and Peak max is the highest per-client queue population observed since startup. |
| TX > TX throttle | Both | Soft-brake watermarks used to pause user-packet flushing when pending writes grow too large and to resume once the backlog falls again. |
| TX > Buffered data | Client, Server | Byte usage in the transmit path. On the client, Queue is the queued byte count, peak is its high-water mark, Socket pending is the amount already handed to the SDL3_net socket and Total pending is queue plus socket backlog. On the server, Queue avg is the average queued outbound bytes across connected clients, Queue max is the largest current queued byte count among them and Queue peak is the highest per-client queued byte usage observed since startup. On both sides, Current DataNet is the size of the packet currently being prepared or flushed and peak is the largest packet seen in the TX path. |
| TX > DataNets | Both | Count of transmitted packets split into System protocol packets and User application packets. |
| TX > Data volume | Both | Total is the number of transmitted bytes since startup, including headers and payloads. Throughput is the average transmit rate since startup shown in human-readable form. |
| TX > Average DataNet size | Both | Average size of transmitted System packets and transmitted User packets. |
| TX > Errors | Both | Throttled counts send attempts deferred because transmission was temporarily backpressured. Limit counts send attempts rejected because packet or queue limits were reached before transmission. Send fail counts low-level transmission failures after a packet had already entered the TX path. |
Classes | |
| class | CRM64Pro::NetTCP |
| NetTCP class. More... | |
Functions | |
| bool | CRM64Pro::NetTCP::info (Sint32 iMode=0) override |
| Request NetTCP Interface information. | |
| eNetResult | CRM64Pro::NetTCP::init (eLogMode eLM) |
| Initialize the NetTCP system. | |
| eNetResult | CRM64Pro::NetTCP::close () |
| Close the NetTCP system. | |
| bool | CRM64Pro::NetTCP::isServer () const |
| Check if the server is running. | |
| bool | CRM64Pro::NetTCP::isClient () const |
| Check if the client is running. | |
| NetIPAddress | CRM64Pro::NetTCP::getIP () const |
| Get the IP address. | |
| eNetResult | CRM64Pro::NetTCP::getClientName (string &sClientName) const |
| Get the client name. | |
| bool | CRM64Pro::NetTCP::setFeatures (eNetTCPFeature eNF, bool bEnable) |
| Set advanced features. | |
| eNetTCPFeature | CRM64Pro::NetTCP::getFeatures () const |
| Get advanced features. | |
| eNetResult | CRM64Pro::NetTCP::connectTo (const string &sHost, Uint16 iPort, const string &sClient, const string &sPassword) |
| Connect to a server. | |
| eNetResult | CRM64Pro::NetTCP::sendData (void *pData, Sint32 iSize, Uint8 bIsQuery=1) |
| Send a data package. | |
| eNetMsg | CRM64Pro::NetTCP::receiveData (void **pData, Uint32 *iSize, Uint8 *senderID=nullptr) |
| Receive a data package (non-blocking method). | |
| eNetResult | CRM64Pro::NetTCP::freeData (void *&pData) |
| Free a received data package. | |
| eNetResult | CRM64Pro::NetTCP::queryKillServer () |
| Query to close the server (and all the connected clients). | |
| eNetResult | CRM64Pro::NetTCP::queryKillClient () |
| Query to kill this client. | |
| eNetResult | CRM64Pro::NetTCP::queryClientsInfo () |
| Query to get updated the information of all connected clients. | |
| Sint32 | CRM64Pro::NetTCP::getPendingWrites () const |
| Query pending outgoing bytes on the local client stream socket. | |
| eNetResult | CRM64Pro::NetTCP::setTXSoftBrake (Uint32 iHighWater, Uint32 iLowWater) |
| Set TX soft-brake watermarks used by the owner-thread flush loops. | |
| eNetResult | CRM64Pro::NetTCP::getTXSoftBrake (Uint32 *iHighWater, Uint32 *iLowWater) const |
| Get TX soft-brake watermarks currently used by NetTCP. | |
| Sint32 | CRM64Pro::NetTCP::getClientsInfo (ClientInfo **cinfo) |
| Get information stored locally about all connected clients. | |
| Sint32 | CRM64Pro::NetTCP::setTimeOut (Sint32 iMs) |
| Set the connection timeout. | |
| Sint32 | CRM64Pro::NetTCP::setSimDelay (Sint32 iMs, Sint32 iMode=0) |
| Simulate a connection delay. | |
| eNetResult | CRM64Pro::NetTCP::createServer (Uint16 iPort, const string &sPassword, Sint32 iDedicated) |
| Create a server. | |
| eNetResult | CRM64Pro::NetTCP::setCoreServerCallback (Sint32(*myCoreServer)(void *pData, Sint32 iSize, void *pObj), void *pObj=nullptr) |
| Set a callback function into the server thread for handling data. | |
| enum CRM64Pro::eNetMsg |
Network messages.
| enum CRM64Pro::eNetResult |
Network result codes.
| Enumerator | |
|---|---|
| NR_OK | Operation completed successfully. |
| NR_NO_INIT | NetTCP is not initialized. |
| NR_IS_INIT | NetTCP is already initialized. |
| NR_ABORT | Operation aborted. |
| NR_CAN_NOT_CONNECT | Connection could not be established. |
| NR_NO_SERVER_RUNNING | No server is currently running. |
| NR_NO_CLIENT_RUNNING | No client is currently running. |
| NR_ONLY_ONE_SERVER | Only one server can run at a time. |
| NR_ONLY_ONE_CLIENT | Only one client can run at a time. |
| NR_WRONG_PORT | Invalid TCP port. |
| NR_OUT_OF_MEMORY | Memory allocation failed. |
| NR_TX_EMPTY_DN | Empty DataNet payload is not allowed. |
| NR_INVALID_CLIENT | Invalid client name or state. |
| NR_DUPLICATED_CLIENT | Client name is already in use. |
| NR_CLIENT_LIMIT_REACHED | Maximum number of clients reached. |
| NR_WRONG_PASSWORD | Wrong server password. |
| NR_LOGIN_DISABLED | Server logins are currently disabled. |
| NR_BAD_PARAMETER | Invalid parameter. |
| NR_RX_LIMIT_REACHED | RX queue limit reached. |
| NR_TX_THROTTLED | Outgoing traffic is temporarily throttled/backpressured. Retry later. |
| NR_CREATE_THREAD | Failed to create the worker thread. |
| NR_CLIENT_INTERNAL | Internal client-side failure. |
| NR_SERVER_INTERNAL | Internal server-side failure. |
| NR_HASH_MISMATCH | Received DataNet failed hash validation. |
| NR_SEQUENCER_MISMATCH | Received DataNet failed sequencer validation. |
| NR_SDLNET_INIT | SDL3_net initialization failed. |
| NR_RX_BAD_HEADER | Failed to receive a valid DataNet header. |
| NR_RX_BAD_DATA | Failed to receive the full DataNet payload. |
| NR_TX_BAD_DATA | Failed to transmit a DataNet. |
| NR_RESOLVE_HOST | Hostname resolution failed. |
| NR_TCP_OPEN | Failed to open the TCP connection. |
| NR_ALLOCATE_SOCKET | Failed to allocate socket resources. |
| NR_ADD_SOCKET | Failed to add the socket to the monitoring set. |
| NR_CHECK_SOCKET | Failed while checking socket status. |
| enum CRM64Pro::eNetTCPFeature : Uint32 |
|
override |
| eNetResult CRM64Pro::NetTCP::init | ( | eLogMode | eLM | ) |
Initialize the NetTCP system.
Before using createServer() or connectTo(), NetTCP must be initialized.
| eLM | dedicated network log mode. Check LM_NULL, LM_STDOUT, LM_FILE, LM_FILEAPPEND and LM_CONSOLE (can be OR'ed). Default is LM_NULL. |
| eNetResult CRM64Pro::NetTCP::close | ( | ) |
Close the NetTCP system.
| bool CRM64Pro::NetTCP::isServer | ( | ) | const |
Check if the server is running.
| bool CRM64Pro::NetTCP::isClient | ( | ) | const |
Check if the client is running.
| NetTCP::NetIPAddress CRM64Pro::NetTCP::getIP | ( | ) | const |
Get the IP address.
| eNetResult CRM64Pro::NetTCP::getClientName | ( | string & | sClientName | ) | const |
Get the client name.
| sClientName | a string containing the client name when it is connected to a server. |
| bool CRM64Pro::NetTCP::setFeatures | ( | eNetTCPFeature | eNF, |
| bool | bEnable ) |
Set advanced features.
| eNF | one or more NetTCP features to modify. |
| bEnable | true to enable the features, false to disable them. |
| eNetTCPFeature CRM64Pro::NetTCP::getFeatures | ( | ) | const |
Get advanced features.
| eNetResult CRM64Pro::NetTCP::connectTo | ( | const string & | sHost, |
| Uint16 | iPort, | ||
| const string & | sClient, | ||
| const string & | sPassword ) |
Connect to a server.
This method attempts to connect to the server during the timeout configured by setTimeOut(). After the TCP connection is established, NetTCP completes the login handshake before returning success.
| sHost | host name or IP of the server to connect to. |
| iPort | the listening server port (1024 to 65535). |
| sClient | client name, must be unique and with a maximum of 16 characters. |
| sPassword | password/passphrase to connect to the server. Maximum length is 64 characters. |
| eNetResult CRM64Pro::NetTCP::sendData | ( | void * | pData, |
| Sint32 | iSize, | ||
| Uint8 | bIsQuery = 1 ) |
Send a data package.
Sends an application payload from the local client to the connected server. In authoritative mode, user packets are evaluated by the CoreServer callback and can be accepted or denied. In non-authoritative mode, user packets are redistributed by the server without callback validation.
| pData | pointer to your data. |
| iSize | size in bytes of your data. |
| bIsQuery | for authoritative mode only. Default 1 allows callback evaluation. Other values bypass evaluation. |
| eNetMsg CRM64Pro::NetTCP::receiveData | ( | void ** | pData, |
| Uint32 * | iSize, | ||
| Uint8 * | senderID = nullptr ) |
Receive a data package (non-blocking method).
Data packages come from server or other clients. Incoming packages are queued; call repeatedly until ::NM_NOTHING is returned.
| pData | pointer to received data package. |
| iSize | pointer to integer with size of received data. |
| senderID | optional pointer to receive the sender's client ID for user DataNets. Pass nullptr if not needed. |
| eNetResult CRM64Pro::NetTCP::freeData | ( | void *& | pData | ) |
Free a received data package.
Release a payload previously returned by receiveData(). Do not use any other deallocation function for this memory.
| pData | pointer to the received data. |
| eNetResult CRM64Pro::NetTCP::queryKillServer | ( | ) |
Query to close the server (and all the connected clients).
Requests a graceful server shutdown. If a local client is connected, the request is sent to the server. If only a local server is running, shutdown begins immediately.
| eNetResult CRM64Pro::NetTCP::queryKillClient | ( | ) |
Query to kill this client.
Requests a graceful disconnection of the local client from the server.
| eNetResult CRM64Pro::NetTCP::queryClientsInfo | ( | ) |
Query to get updated the information of all connected clients.
| Sint32 CRM64Pro::NetTCP::getPendingWrites | ( | ) | const |
Query pending outgoing bytes on the local client stream socket.
| eNetResult CRM64Pro::NetTCP::setTXSoftBrake | ( | Uint32 | iHighWater, |
| Uint32 | iLowWater ) |
Set TX soft-brake watermarks used by the owner-thread flush loops.
When pending socket writes for user traffic reach the high watermark, NetTCP temporarily pauses further user-packet flushing until the backlog drops to the low watermark. Control/login traffic is not affected by this soft-brake.
| iHighWater | high watermark in bytes. Must be >= low watermark. |
| iLowWater | low watermark in bytes. Must be <= high watermark. |
| eNetResult CRM64Pro::NetTCP::getTXSoftBrake | ( | Uint32 * | iHighWater, |
| Uint32 * | iLowWater ) const |
Get TX soft-brake watermarks currently used by NetTCP.
| iHighWater | output pointer to receive the high watermark in bytes. |
| iLowWater | output pointer to receive the low watermark in bytes. |
| Sint32 CRM64Pro::NetTCP::getClientsInfo | ( | ClientInfo ** | cinfo | ) |
Get information stored locally about all connected clients.
Client info table auto-updates on connect/disconnect. For real latency, call queryClientsInfo() first (not needed if client runs with server).
| cinfo | pointer to the local ClientInfo table. |
| Sint32 CRM64Pro::NetTCP::setTimeOut | ( | Sint32 | iMs | ) |
Set the connection timeout.
Sets the base network timeout used by hostname resolution, TCP connect, client login waits, server pending-login lifetime and RX partial-read progress watchdogs. Login waits use the configured timeout, server pending-logins use twice that value and partial-read progress uses max(1000 ms, iMs / 2).
| iMs | timeout in milliseconds. Minimum 500ms. Default 2000ms. |
| Sint32 CRM64Pro::NetTCP::setSimDelay | ( | Sint32 | iMs, |
| Sint32 | iMode = 0 ) |
Simulate a connection delay.
Only works for clients. Can be changed at any time.
| iMs | simulated delay in milliseconds [0-2500]. Default 0. |
| iMode | Reserved for future use. |
| eNetResult CRM64Pro::NetTCP::createServer | ( | Uint16 | iPort, |
| const string & | sPassword, | ||
| Sint32 | iDedicated ) |
Create a server.
| iPort | the listening server port (1024 to 65535). |
| sPassword | server password/passphrase. Maximum length is 64 characters. |
| iDedicated | 1 for stand-alone mode (call blocks until server closes). 0 for threaded mode (call returns immediately). |
| eNetResult CRM64Pro::NetTCP::setCoreServerCallback | ( | Sint32(* | myCoreServer )(void *pData, Sint32 iSize, void *pObj), |
| void * | pObj = nullptr ) |
Set a callback function into the server thread for handling data.
| myCoreServer | callback function taking data pointer, size, and optional pObj. When this callback is set, the server runs in authoritative mode. Use nullptr to disable it and return to non-authoritative mode. The callback runs on the server thread. Return 0 to accept the user packet or a negative value to deny it. |
| pObj | pointer to data/function/static method. Default nullptr (unused). |