TCP Socket functions and communication flow. More...
typedef uint32_t(* | netTCP_cb_t) (int32_t socket, netTCP_Event event, const NET_ADDR *addr, const uint8_t *buf, uint32_t len) |
TCP Event callback function. | |
int32_t | netTCP_GetSocket (netTCP_cb_t cb_func) |
Allocate a free TCP socket. [thread-safe]. | |
netStatus | netTCP_ReleaseSocket (int32_t socket) |
Release TCP socket and free resources. [thread-safe]. | |
netStatus | netTCP_Listen (int32_t socket, uint16_t port) |
Open TCP socket for incoming connection. [thread-safe]. | |
netStatus | netTCP_Connect (int32_t socket, const NET_ADDR *addr, uint16_t local_port) |
Initiate a TCP connection to a remote node. [thread-safe]. | |
netStatus | netTCP_Close (int32_t socket) |
Stop TCP communication and start closing procedure. [thread-safe]. | |
netStatus | netTCP_Abort (int32_t socket) |
Instantly stop TCP communication. [thread-safe]. | |
uint32_t | netTCP_GetMaxSegmentSize (int32_t socket) |
Determine maximum number of data bytes that can be sent in TCP packet. [thread-safe]. | |
uint8_t * | netTCP_GetBuffer (uint32_t size) |
Allocate memory for TCP send buffer. [thread-safe]. | |
bool | netTCP_SendReady (int32_t socket) |
Check if TCP socket can send data. [thread-safe]. | |
netStatus | netTCP_Send (int32_t socket, uint8_t *buf, uint32_t len) |
Send a data packet to remote node. [thread-safe]. | |
netTCP_State | netTCP_GetState (int32_t socket) |
Determine current state of a TCP socket. [thread-safe]. | |
netStatus | netTCP_ResetReceiveWindow (int32_t socket) |
Reset TCP window size to a default value from the configuration. [thread-safe]. | |
netStatus | netTCP_SetOption (int32_t socket, netTCP_Option option, uint32_t val) |
Set TCP socket IP option. [thread-safe]. | |
uint16_t | netTCP_GetLocalPort (int32_t socket) |
Retrieve local port number of TCP socket. [thread-safe]. | |
netStatus | netTCP_GetPeer (int32_t socket, NET_ADDR *addr, uint32_t addr_len) |
Retrieve IP address and port number of remote peer. [thread-safe]. | |
uint32_t | netTCP_GetTimer (int32_t socket) |
Determine TCP socket connection timeout. [thread-safe]. | |
TCP Socket functions and communication flow.
TCP operations can be divided into three distinct phases (SYN, SYN-ACK, ACK). All connections must be properly established in this three-step handshake process before any data can be transfered. After the data transfer has finished, the connection termination closes established sockets and releases all allocated resources. The basic communication flow using TCP sockets is shown in this picture:
For establishing a connection, TCP uses a three-way handshake. Before a client can connect to a server, the server must first open a socket for incoming connections (using netTCP_Listen): this is called a passive open. Once the passive open is established, a client may initiate an active open. To establish a connection, the three-way handshake takes place:
At this point, a full-duplex communication is established.
The connection can be terminated from each side independently. When an endpoint wishes to stop the connection (by calling netTCP_Close), it transmits a FIN packet, which the other end acknowledges with an ACK. Therefore, a typical connection close requires a pair of FIN and ACK segments from each TCP endpoint and takes some time. After both FIN/ACK exchanges are concluded, the side that sent the first FIN before receiving one waits for a timeout before finally closing the connection, during which time the local port is unavailable for new connections; this prevents confusion due to delayed packets being delivered during subsequent connections.
The TCP Socket API distinguishes two operation modes: Server and Client. Both modes have distinct functions that can either be used in the respective mode only or are available for multiple operation modes.
The function netTCP_Listen opens a TCP socket on a local port for any incoming connection and starts TCP Server Mode. The next free socket can be allocated using the function netTCP_GetSocket. This function requires a callback function to be present that is called by the Network Core whenever a TCP event occurs. The TCP Server callback function is inside the module TCP_Socket_Server.c. To add the module to your project, simply right-click on the Source group, select Add New Item to Group, then click on User Code Template and scroll in the template files list until you find the TCP Socket Server template. Customize this module to the application's needs.
It is not allowed to call netTCP_Listen with a port number of 0, because this is a reserved port number. To determine the state of a TCP socket, use netTCP_GetState. The user application can monitor the progress when establishing or closing a connection with this function.
As soon as a client requests to connect, the socket/port combination is used for the data transfer. For that, the function netTCP_GetMaxSegmentSize helps to determine the maximum number of data bytes that can be sent in a TCP packet. Call this function after the remote client is connected. To retrieve information about the client that is connected to the server, use netTCP_GetPeer which returns the IP address and port of the connected remote client.
For the data transmission, the functions netTCP_GetBuffer, netTCP_SendReady, and netTCP_Send are used. The first one allocates memory for the TCP send buffer. The second one checks if the TCP socket is free for sending data, while the third one does the actual transmission.
To instantly stop TCP communication (even during data transmission), use netTCP_Abort. Use this only for cases, where the transmission really needs to be aborted. Normally, TCP communication will be stopped using netTCP_Close. In server mode, this does not close the socket, but only ends the active client connection. To fully close the listener socket as well, call netTCP_Close a second time. In that case, call netTCP_ReleaseSocket as well, as this function finally frees the memory used by the TCP socket.
Code Example
The function netTCP_Connect initiates a connection to a remote TCP server and starts TCP Client Mode. You need to specify the socket number, the IP address and port of the remote machine and the local port.
If netTCP_Connect is called with a local port number of 0, the Network Core determines which port to use. Later, this information can be retrieved using the function netTCP_GetLocalPort. To determine the state of a TCP socket, use netTCP_GetState. The user application can monitor the progress when establishing or closing a connection with this function.
As soon as a client requests to connect, the socket/port combination is used for the data transfer. For that, the function netTCP_GetMaxSegmentSize helps to determine the maximum number of data bytes that can be sent in a TCP packet. Call this function after the client is connected to remote server.
To be able to successfully send data via TCP, you first need to request a buffer to be allocated using netTCP_GetBuffer. Then, fill the buffer with the data to be sent and send it using netTCP_Send. The buffer will be released by the Network Component automatically. If the buffer is not valid (not allocated with the netTCP_GetBuffer function), the buffer is ignored.
The Network Component does not send 0-length packets. So it is possible to release a buffer that has been allocated, by simply calling netTCP_Send with parameter len = 0.
The user code template TCP_Socket_Client.c contains an exemplary send function, called send_data. The send_data function must be implemented as a state machine. It opens an active TCP connection, sends data, and closes the TCP connection at the end. To add the template to your project, simply right-click on the Source group, select Add New Item to Group, then click on User Code Template and scroll in the template files list until you find the TCP Socket Client template. Adapt the send_data function to your application's needs.
To instantly stop TCP communication (even during data transmission), use netTCP_Abort. Use this only for cases, where the transmission really needs to be aborted. In client mode, TCP communication will be stopped using netTCP_Close. The TCP socket will be closed. Subsequently, call netTCP_ReleaseSocket as well, as this function finally frees the memory used by the TCP socket.
Code Example
uint32_t(* netTCP_cb_t)(int32_t socket, netTCP_Event event, const NET_ADDR *addr, const uint8_t *buf, uint32_t len) |
TCP Event callback function.
[in] | socket | TCP socket handle. |
[in] | event | Event type as shown in the table below (netTCP_Event). |
[in] | addr | Pointer to the structure containing the remote IP address and port number. |
[in] | buf | Pointer to buffer containing the received data. |
[in] | len | Number of bytes in the received packet. |
Is the type definition for the TCP callback function. The Network Core calls the callback function whenever a TCP event occurs.
The argument socket is the TCP socket handle of the local machine.
The argument addr is a pointer to the buffer containing the IP address and port of the remote machine.
The argument event specifies the type of event that occurred as shown in the table below or netTCP_Event.
The argument buf points to a buffer containing the received data.
The argument len specifies the number of received data bytes.
The Network Core uses the return value of the callback function only when the event is netTCP_EventConnect. It uses the return value to decide whether to accept or reject an incoming connection when the TCP socket is listening. If the listener function returns 1, then it accepts the incoming connection. If the listener function returns 0, it rejects the incoming connection. Thus, you can define the listener function to selectively reject incoming connections from particular IP addresses.
Event Type | Description |
---|---|
netTCP_EventConnect | A Connect Request has been received from a remote client that wants to connect to the server |
netTCP_EventEstablished | The TCP socket has connected to the remote machine |
netTCP_EventClosed | The TCP connection has been properly closed |
netTCP_EventAbort | The TCP connection has been aborted |
netTCP_EventACK | Acknowledgment has been received from the remote host for the previously sent data |
netTCP_EventData | A TCP data packet has been received |
Parameter for:
Code Example TCP Client
Code Example TCP Server
netStatus netTCP_Abort | ( | int32_t | socket | ) |
Instantly stop TCP communication. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_Abort closes the TCP connection immediately by sending a TCP frame with the RESET flag set to the remote machine.
The argument socket specifies the handle of the socket.
The Network Core calls the listener callback function only when a remote peer has aborted the connection. If the aborted socket is initiated locally by calling netTCP_Abort, then the callback function is not called.
Possible netStatus return values:
Code Example (see netTCP_ReleaseSocket)
netStatus netTCP_Close | ( | int32_t | socket | ) |
Stop TCP communication and start closing procedure. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_Close initiates the procedure to close the TCP connection. It might take some time to close the connection.
The argument socket specifies the socket handle.
The Network Core calls the listener callback function only when a remote peer has closed the connection. If the socket is closed locally by calling netTCP_Close, then the callback function is not called.
When a socket is used in the netTCP_Listen functions, the socket does not close by calling netTCP_Close. Only the active connection is closed, and the socket will be available for new incoming connection. To close such a socket, the function netTCP_Close needs to be called twice.
Possible netStatus return values:
Code Example
Initiate a TCP connection to a remote node. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
[in] | addr | structure containing remote IP address and port. |
[in] | local_port | local port number.
|
The function netTCP_Connect initiates a connection to a remote server.
The argument socket is a socket handle on the local machine for communicating.
The argument addr points to the buffer containing the IP address and port of the remote socket server.
The argument local_port specifies the port on the local machine. If local_port is set to 0, then the Network Core allocates the first free TCP port automatically. If you need the port number later, use netTCP_GetLocalPort to retrieve this information.
Possible netStatus return values:
Code Example IPv4
Code Example IPv6
uint8_t * netTCP_GetBuffer | ( | uint32_t | size | ) |
Allocate memory for TCP send buffer. [thread-safe].
[in] | size | number of bytes to allocate. |
The function netTCP_GetBuffer allocates memory for the TCP send buffer into which your application can write the outgoing data packet.
The argument size specifies the number of data bytes that the application wants to send.
After the TCP frame has been sent and an acknowledgment has been received from the remote host, the Network Core automatically de-allocates the memory used by the send buffer in the netTCP_Send function.
A default Maximum Segment Size (MSS) of 1440 bytes is defined at start-up. However, when establishing a connection with a remote machine, the Network Core might negotiate a different (smaller) value for MSS. Use netTCP_GetMaxSegmentSize to check the available MSS for the current connection.
Code Example (see netTCP_Send)
uint16_t netTCP_GetLocalPort | ( | int32_t | socket | ) |
Retrieve local port number of TCP socket. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_GetLocalPort returns the local TCP port that is used for a specific socket. This is useful if you have not specified a port in the function netTCP_Connect, as the system sets the port automatically then.
The argument socket specifies the local socket handle that is to be used.
Code Example
uint32_t netTCP_GetMaxSegmentSize | ( | int32_t | socket | ) |
Determine maximum number of data bytes that can be sent in TCP packet. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_GetMaxSegmentSize determines the maximum number of bytes that can be sent in the TCP packet (Maximum Segment Size).
The argument socket specifies the handle of the TCP socket.
A default Maximum Segment Size (MSS) of 1440 bytes is defined at start-up. However, when establishing a connection with a remote machine, the Network Core might negotiate a different (smaller) value for MSS.
Code Example (see netTCP_Send)
Retrieve IP address and port number of remote peer. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
[out] | addr | structure that will receive IP address and port number. |
[in] | addr_len | size of NET_ADDR structure for remote peer. |
The function netTCP_GetPeer provides the IP address and port of the remote client that is connected.
The argument socket specifies the local socket handle that is to be used.
The argument addr points to the buffer where the IP address and port of the remote machine will be stored.
The argument addr_len specifies the length of the addr structure. The Network Core checks the length, if the library can store the IP address of the remote peer into the structure. The IP address contains an IPv4 or IPv6 address.
Possible netStatus return values:
Code Example
int32_t netTCP_GetSocket | ( | netTCP_cb_t | cb_func | ) |
Allocate a free TCP socket. [thread-safe].
[in] | cb_func | event listening callback function. |
The function netTCP_GetSocket allocates a free TCP socket. The function initializes all the state variables of the TCP socket to the default state.
The argument cb_func is the event callback function of the TCP socket. The Network Core calls this function whenever a TCP event occurs. Refer to netTCP_cb_t.
Possible netStatus return values:
Code Example
netTCP_State netTCP_GetState | ( | int32_t | socket | ) |
Determine current state of a TCP socket. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_GetState determines the current state of the TCP socket. The application can monitor the progress when establishing or closing a connection with this function. The most useful state values are netTCP_StateCLOSED, netTCP_StateLISTEN, and netTCP_StateESTABLISHED.
The argument socket specifies the socket handle.
The netTCP_GetState function returns the current state of the TCP socket:
State | Description |
---|---|
netTCP_StateINVALID | Socket is not available (not in the range of sockets specified in the NET_Config_TCP.h file). |
netTCP_StateUNUSED | Socket is free and not allocated yet. The function cannot return this value. |
netTCP_StateCLOSED | Socket is allocated to an application but the connection is closed. |
netTCP_StateLISTEN | Socket is listening for incoming connections. |
netTCP_StateSYN_RECEIVED | Socket has received a TCP packet with the flag SYN set. |
netTCP_StateSYN_SENT | Socket has sent a TCP packet with the flag SYN set. |
netTCP_StateFIN_WAIT_1 | Socket has sent a FIN packet, to start the closing of the connection. |
netTCP_StateFIN_WAIT_2 | Socket has received acknowledgment from the remote machine for the FIN packet it sent out from the local machine. Socket is now waiting for a FIN packet from the remote machine. |
netTCP_StateCLOSING | Socket has received a FIN packet from the remote machine independently |
netTCP_StateLAST_ACK | Socket is waiting for the last ACK packet to the FIN packet it sent out. |
netTCP_StateTIME_WAIT | Socket is waiting on a 2 MSS timeout before closing the connection. |
netTCP_StateESTABLISHED | Socket has established a TCP connection. You can transfer data only in this state. |
Code Example (see netTCP_Connect)
uint32_t netTCP_GetTimer | ( | int32_t | socket | ) |
Determine TCP socket connection timeout. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_GetTimer returns the timer value of a time out or the current keep alive value. When the time out expires, the Network Core will either close the socket, or send a keep-alive frame.
The argument socket specifies the local socket handle that is to be used.
Code Example
netStatus netTCP_Listen | ( | int32_t | socket, |
uint16_t | port | ||
) |
Open TCP socket for incoming connection. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
[in] | port | local port number. |
The function netTCP_Listen opens a socket for incoming connections by causing the socket to listen at a local TCP port.
The argument socket specifies the socket handle to listen on the local machine.
The argument port specifies the TCP port number to listen at. If the argument port is 0, the function returns error, because this port is reserved. If you need the port number later, use netTCP_GetLocalPort to retrieve this information.
Possible netStatus return values:
Code Example
netStatus netTCP_ReleaseSocket | ( | int32_t | socket | ) |
Release TCP socket and free resources. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_ReleaseSocket de-allocates the memory used by the TCP socket.
The argument socket specifies the handle of the socket to be released.
Possible netStatus return values:
Code Example
netStatus netTCP_ResetReceiveWindow | ( | int32_t | socket | ) |
Reset TCP window size to a default value from the configuration. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_ResetReceiveWindow resets the TCP window size to a default value defined with TCP_RECEIVE_WIN_SIZE
macro in the Net_Config_TCP.h file.
The argument socket specifies the handle of the socket for which to reset the window size.
This function can only be used with sockets that have a TCP flow control enabled. Enable a TCP flow control for the socket by calling the netTCP_SetOption function with the netTCP_OptionFlowControl enabled. This socket option enables using a Sliding Window protocol in receive.
In Flow Control mode, each received data packet reduces the receiving Window Size by the number of data bytes received in the packet. Soon the window size becomes very small or 0. The remote host stops sending data and waits for a window update. As soon as the received data is processed, we can call a netTCP_ResetReceiveWindow function to reopen the receiver window for further incoming data.
Depending on the context from where this function was called, it performs the following actions:
Possible netStatus return values:
Code Example
netStatus netTCP_Send | ( | int32_t | socket, |
uint8_t * | buf, | ||
uint32_t | len | ||
) |
Send a data packet to remote node. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
[in] | buf | buffer containing the data. |
[in] | len | length of data in bytes. |
The function netTCP_Send sends the data packet to a remote machine.
The argument socket specifies the socket handle to use for communication on the local machine.
The argument buf points to the constructed TCP data packet.
The argument len specifies the number of bytes in the data packet.
If the netTCP_Send fails to send the data, it releases the memory buffer specified with the argument buf and returns with an error status. The function cannot send data if:
Possible netStatus return values:
Code Example
bool netTCP_SendReady | ( | int32_t | socket | ) |
Check if TCP socket can send data. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
The function netTCP_SendReady determines whether the TCP socket can send data. It does this by checking whether the TCP connection has been established and whether the socket has received an acknowledgment from the remote machine for data sent previously.
The argument socket specifies the socket handle.
Code Example (see netTCP_Send)
netStatus netTCP_SetOption | ( | int32_t | socket, |
netTCP_Option | option, | ||
uint32_t | val | ||
) |
Set TCP socket IP option. [thread-safe].
[in] | socket | socket handle obtained with netTCP_GetSocket. |
[in] | option | option name as defined with netTCP_Option. |
[in] | val | option value. |
The function netTCP_SetOption sets different options for a TCP socket identified by the argument socket.
The argument option specifies the TCP option that is to be set (see below).
The argument val carries the value of the TCP option that is to be set.
Option | Description | Value |
---|---|---|
netTCP_OptionTOS | IPv4 Type of Service | val=TOS |
netTCP_OptionTrafficClass | IPv6 Traffic Class | val=TrafficClass |
netTCP_OptionTimeout | TCP Idle Timeout | val=timeout (in seconds) |
netTCP_OptionKeepAlive | TCP Keep Alive | val: 0=disabled (default), 1=enabled |
netTCP_OptionFlowControl | TCP Flow Control | val: 0=disabled (default), 1=enabled |
netTCP_OptionDelayedACK | TCP Delayed Acknowledgment | val: 0=disabled (default), 1=enabled |
Possible netStatus return values:
Code Example