Manages network connections via TCP/IP sockets.
The NetSocket class provides a simple way of managing outbound TCP/IP socket communications. It can connect to remote TCP servers, exchange UDP datagrams when the UDP flag is set, and optionally use SSL. Inbound listening and accepted client management are provided by the NetServer subclass, with each accepted TCP connection represented by a ClientSocket.
The design of the NetSocket class caters to asynchronous (non-blocking) communication. This is achieved primarily through callback fields - connection alerts are managed by Feedback, incoming data is received through Incoming and readiness for outgoing data is supported by Outgoing.
After a connection has been established, data may be written using any of the following methods:
It is possible to write to a NetSocket object before the connection to a server is established. Doing so will buffer the data in the socket until the connection with the server has been initiated, at which point the data will be immediately sent.
Use NetServer when a program needs to bind a local port and accept inbound clients. NetServer inherits common socket fields from NetSocket, reports client state changes through Feedback with a ClientSocket parameter, and exposes active clients through its Clients field. Data for accepted TCP clients is read from and written to ClientSocket objects.
The NetSocket class consists of the following fields:
Access | Name | Type | Comment | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Address | STRING | An IP address or domain name to connect to. | |||||||||||||||||||
For NetSocket clients, if this field is set with an IP address or domain name prior to initialisation, an attempt to connect to that location will be made when the object is initialised. Post-initialisation this field cannot be set by the client, however calls to Connect() will result in it being updated so that it always reflects the named address of the current connection. For NetServer listeners, this inherited field identifies the local address to bind before initialisation. Use | |||||||||||||||||||||
| ClientData | APTR | A client-defined value that can be useful in action notify events. | |||||||||||||||||||
This is a free-entry field value that can store client data for future reference. | |||||||||||||||||||||
| Error | ERR | Information about the last error that occurred during a NetSocket operation | |||||||||||||||||||
This field describes the last error that occurred during a NetSocket operation: In the case where a NetSocket object enters the
| |||||||||||||||||||||
| Feedback | FUNCTION | A callback trigger for when the state of the NetSocket is changed. | |||||||||||||||||||
The client can define a function in this field to receive notifications whenever the state of the socket changes - typically connection messages. For NetSocket clients, the function must follow the prototype The first parameter refers to the object to which the function is subscribed. For NetServer listeners, | |||||||||||||||||||||
| Flags | NSF | Optional flags. | |||||||||||||||||||
| |||||||||||||||||||||
| Handle | APTR | Platform specific reference to the network socket handle. | |||||||||||||||||||
| Incoming | FUNCTION | Callback that is triggered when the socket receives data. | |||||||||||||||||||
The Incoming field can be set with a custom function that will be called whenever the socket receives data. The function prototype for C++ is The Retrieve data from the socket with the Read() action. Reading at least some of the data from the socket is compulsory - if the function does not do this then the data will be cleared from the socket when the function returns. If the callback function returns/raises | |||||||||||||||||||||
| MaxPacketSize | INT | Maximum UDP packet size for sending and receiving data. | |||||||||||||||||||
This field sets the maximum size in bytes for UDP packets when sending or receiving data. It only applies to UDP sockets and is ignored for TCP connections. The default value is 65507 bytes, which is the maximum payload size for UDP packets (65535 - 8 bytes UDP header - 20 bytes IP header). If you attempt to send a packet larger than MaxPacketSize, a warning will be logged and the operation may fail. When receiving data, packets larger than this size will be truncated. | |||||||||||||||||||||
| MsgLimit | INT | Limits the size of incoming and outgoing data packets. | |||||||||||||||||||
This field limits the size of incoming and outgoing message queues (each socket connection receives two queues assigned to both incoming and outgoing messages). The size is defined in bytes. Sending or receiving messages that overflow the queue results in the connection being terminated with an error. The default setting is 1 megabyte. | |||||||||||||||||||||
| MulticastTTL | INT | Time-to-live (hop limit) for multicast packets. | |||||||||||||||||||
This field sets the time-to-live (TTL) value for multicast packets sent from UDP sockets. The TTL determines how many network hops (routers) a multicast packet can traverse before being discarded. This helps prevent multicast traffic from flooding the network indefinitely. The default TTL is 1, which restricts multicast to the local network segment. Higher values allow multicast packets to traverse more network boundaries:
| |||||||||||||||||||||
| OutQueueSize | INT | The number of bytes on the socket's outgoing queue. | |||||||||||||||||||
| Outgoing | FUNCTION | Callback that is triggered when a socket is ready to send data. | |||||||||||||||||||
The Outgoing field can be set with a custom function that will be called whenever the socket is ready to send data. For NetSocket clients the function must be in the format To send data from a NetSocket object, call the Write() action. To send data from a NetServer to a connected client, call ClientSocket⇒Write() on the target client socket. If the callback function returns an error other than | |||||||||||||||||||||
| Port | INT | The port number to use for connections. | |||||||||||||||||||
| State | NTC | The current connection state of the NetSocket object. | |||||||||||||||||||
The State reflects the connection state of the NetSocket. If the Feedback field is defined with a function, it will be called automatically whenever the state is changed. Note that the ClientSocket parameter will be NULL when the Feedback function is called. For NetServer listeners this State value should not be used as it cannot reflect the state of all connected client sockets. When read from a NetServer, this inherited field reports
| |||||||||||||||||||||
The following actions are currently supported:
| DataFeed | Streams raw data to the socket for writing. | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ERR acDataFeed(*Object, OBJECTID Object, DATA Datatype, std::span<const int8_t> Buffer)
Data sent to a NetSocket through this action is written using the same buffered behaviour as Write(). | ||||||||||||||||||||||
| Disable | Disables sending and receiving on the socket. | |||||||||||||||||||||
ERR acDisable(*Object) This method will stop all sending and receiving of data over the socket. This is irreversible. Error Codes
| ||||||||||||||||||||||
| Read | Read information from the socket. | |||||||||||||||||||||
ERR acRead(*Object, std::span<int8_t> Buffer, INT *Result)
The Read() action will read incoming data from the socket and write it to the provided buffer. If the socket connection is safe, success will always be returned by this action regardless of whether or not data was available. Almost all other return codes indicate permanent failure and the socket connection will be closed when the action returns. Because NetSocket objects are non-blocking, reading from the socket is normally performed in the Incoming callback. Reading from the socket when no data is available will result in an immediate return with no output. Error Codes
| ||||||||||||||||||||||
| Write | Writes data to the socket. | |||||||||||||||||||||
ERR acWrite(*Object, std::span<const int8_t> Buffer, INT *Result)
Writing data to a socket will send raw data to the remote client or server. Write connections are buffered, so any data overflow generated in a call to this action will be buffered into a software queue. Resource limits placed on the software queue are governed by the MsgLimit field setting. Do not use this action on a NetServer listener. Instead, write to the ClientSocket object that will receive the data. It is possible to write to a socket in advance of any connection being made. The netsocket will queue the data and automatically send it once the first connection has been made. | ||||||||||||||||||||||
The following methods are currently supported:
| Connect | Connects a NetSocket to an address. | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ERR ns::Connect(OBJECTPTR Object, STRVIEW Address, INT Port, DOUBLE Timeout)
This method initiates the connection process with a target IP address. The address to connect to can be specified either as a domain name, in which case the domain name is first resolved to an IP address, or the address can be specified in standard IP notation. This method is non-blocking. It will return immediately and the connection will be resolved once the server responds to the connection request or an error occurs. Client code should subscribe to the State field to respond to changes to the connection state. Pre-Condition: Must be in a connection state of Post-Condition: If this method returns Error Codes
| |||||||||||||||||||||||||
| GetLocalIPAddress | Returns the IP address that the socket is locally bound to. | ||||||||||||||||||||||||
ERR ns::GetLocalIPAddress(OBJECTPTR Object, struct IPAddress * Address)
This method performs the POSIX equivalent of Error Codes
| |||||||||||||||||||||||||
| JoinMulticastGroup | Join a multicast group for receiving multicast packets (UDP only). | ||||||||||||||||||||||||
ERR ns::JoinMulticastGroup(OBJECTPTR Object, STRVIEW Group)
This method joins a multicast group, allowing the socket to receive packets sent to the specified multicast address. This is only available for UDP sockets. The socket must be bound to a local address before joining a multicast group. Error Codes
| |||||||||||||||||||||||||
| LeaveMulticastGroup | Leave a multicast group (UDP only). | ||||||||||||||||||||||||
ERR ns::LeaveMulticastGroup(OBJECTPTR Object, STRVIEW Group)
This method leaves a previously joined multicast group, stopping the reception of packets sent to the specified multicast address. Error Codes
| |||||||||||||||||||||||||
| RecvFrom | Receive a datagram packet from any address (UDP only). | ||||||||||||||||||||||||
ERR ns::RecvFrom(OBJECTPTR Object, struct IPAddress * Source, std::span<int8_t> Buffer, INT * BytesRead)
This method receives a datagram packet from any source address. It is only available for sockets configured with the UDP flag. Unlike TCP connections, UDP is connectionless so packets can be received from any source without establishing a connection first. The method is non-blocking and will return immediately. If no data is available, The source address and port of the received packet will be provided in the output parameters. For TCP sockets, use the standard Read action instead. Error Codes
| |||||||||||||||||||||||||
| SendTo | Send a datagram packet to a specific address (UDP only). | ||||||||||||||||||||||||
ERR ns::SendTo(OBJECTPTR Object, struct IPAddress * Dest, std::span<const int8_t> Data, INT * BytesSent)
This method sends a datagram packet to a specified IP address and port. It is only available for sockets configured with the UDP flag. Unlike TCP connections, UDP is connectionless so packets can be sent to any address without establishing a connection first. The method is non-blocking and will return immediately. If the network buffer is full, an For TCP sockets, use the standard Write action instead. Error Codes
| |||||||||||||||||||||||||
Address types for the IPAddress structure.
| Name | Description |
|---|---|
| IPADDR::V4 | |
| IPADDR::V6 |
NetSocket options
| Name | Description |
|---|---|
| NSF::BROADCAST | Enable broadcast (UDP only). |
| NSF::DISABLE_SERVER_VERIFY | Disable SSL server certificate verification for client sockets (testing only). |
| NSF::KEEP_ALIVE | Enable TCP keep-alive probes using operating system defaults. |
| NSF::LOG_ALL | Print extra log messages. |
| NSF::MULTI_CONNECT | Allow multiple connections from the same IP (NetServer only). |
| NSF::SSL | Use Secure Sockets Layer for all communication. |
| NSF::SYNCHRONOUS | Use synchronous (blocking) network calls. |
| NSF::UDP | Use UDP (connectionless datagram protocol) instead of TCP. |
NetSocket states
| Name | Description |
|---|---|
| NTC::CONNECTED | There is an active connection at present. |
| NTC::CONNECTING | A connection is being established. |
| NTC::DISCONNECTED | There is no connection. |
| NTC::HANDSHAKING | An SSL connection is being established. |
| NTC::MULTISTATE | A NetServer reports MULTISTATE because accepted ClientSocket objects track their own states. |
| NTC::RESOLVING | The host name is being resolved. |
| Field | Type | Description |
|---|---|---|
| Data | INT | 128-bit array for supporting both V4 (32-bit host order) and V6 (8-bit byte order) IP addresses. |
| Type | IPADDR | Identifies the address Data value as a V4 or V6 address type. |
| Port | INT | For UDP packets, identifies the client port number in host byte order. |