It provides reliable stream-based connections over unreliable networks, and forms the foundation for HTTP, SMTP, and many other protocol standards.
Connections made over TCP guarantee data transfer at the expense of throughput. Connections are made through a three-way handshake process, ensuring a one-to- one connection. Remote nodes advertise how much data they are ready to receive, and all data transmitted must be acknowledged. If a remote node fails to acknowledge the receipt of data, it is automatically retransmitted. This ensures that network errors such as lost, corrupted, or out-of-order packets are automatically corrected.
To accomplish this, TCP must operate in a buffer. Once the transmit buffer is full, no more data can be sent until the remote node has acknowledged receipt. For the Microchip TCP/IP Stack, the application must return to the main stack loop in order for this to happen. Likewise, the remote node cannot transmit more data until the local device has acknowledged receipt and that space is available in the buffer. When a local application needs to read more data, it must return to the main stack loop and wait for a new packet to arrive.
The TCP flow diagram below provides an overview for the use of the TCP module:
Sockets are opened using TCPOpen. This function can either open a listening socket to wait for client connections, or can make a client connection to the remote node. The remote node can be specified by a host name string to be resolved in DNS, an IP address, or a NODE_INFO struct containing previously resolved IP and MAC address information.
Once connected, applications can read and write data. On each entry, the application must verify that the socket is still connected. For most applications a call to TCPIsConnected will be sufficient, but TCPWasReset may also be used for listening sockets that may turn over quickly.
To write data, call TCPIsPutReady to check how much space is available. Then, call any of the TCPPut family of functions to write data as space is available. Once complete, call TCPFlush to transmit data immediately. Alternately, return to the main stack loop. Data will be transmitted when either
To read data, call TCPIsGetReady to determine how many bytes are ready to be retrieved. Then use the TCPGet family of functions to read data from the socket, and/or the TCPFindEx family of functions to locate data in the buffer. When no more data remains, return to the main stack loop to wait for more data to arrive.
If the application needs to close the connection, call TCPDisconnect, then return to the main stack loop and wait for the remote node to acknowledge the disconnection. Client sockets will return to the idle state, while listening sockets will wait for a new connection.
For more information read the associated RFC.
Files | |
file | TCP.c |
Transmission Control Protocol (TCP) Communications Layer. | |
file | TCP.h |
TCP Module Defs for Microchip TCP/IP Stack. | |
Functions | |
BOOL | TCPWasReset (TCP_SOCKET hTCP) |
Self-clearing semaphore inidicating socket reset. | |
BOOL | TCPIsConnected (TCP_SOCKET hTCP) |
Determines if a socket has an established connection. | |
void | TCPDisconnect (TCP_SOCKET hTCP) |
Disconnects an open socket. | |
WORD | TCPIsPutReady (TCP_SOCKET hTCP) |
Determines how much free space is available in the TCP TX buffer. | |
BOOL | TCPPut (TCP_SOCKET hTCP, BYTE byte) |
Writes a single byte to a TCP socket. | |
WORD | TCPPutArray (TCP_SOCKET hTCP, BYTE *Data, WORD Len) |
Writes an array from RAM to a TCP socket. | |
BYTE * | TCPPutString (TCP_SOCKET hTCP, BYTE *Data) |
Writes a null-terminated string from RAM to a TCP socket. | |
WORD | TCPIsGetReady (TCP_SOCKET hTCP) |
Determines how many bytes can be read from the TCP RX buffer. | |
BOOL | TCPGet (TCP_SOCKET hTCP, BYTE *byte) |
Retrieves a single byte to a TCP socket. | |
WORD | TCPFindEx (TCP_SOCKET hTCP, BYTE cFind, WORD wStart, WORD wSearchLen, BOOL bTextCompare) |
Searches for a byte in the TCP RX buffer. | |
void | TCPFlush (TCP_SOCKET hTCP) |
Immediately transmits all pending TX data. | |
TCP_SOCKET | TCPOpen (DWORD dwRemoteHost, BYTE vRemoteHostType, WORD wPort, BYTE vSocketPurpose) |
Opens a TCP socket for listening or as a client. |
void TCPDisconnect | ( | TCP_SOCKET | hTCP | ) |
Disconnects an open socket.
This function closes a connection to a remote node by sending a FIN. The function can be called a second time to force a socket closed by sending a RST packet. This is useful when the application knows that the remote node will not send an ACK (if it has crashed or lost its link), or when the application needs to reuse the socket immediately regardless of whether or not the remote node would like to transmit more data before closing.
hTCP | The socket to check. |
WORD TCPFindEx | ( | TCP_SOCKET | hTCP, | |
BYTE | cFind, | |||
WORD | wStart, | |||
WORD | wSearchLen, | |||
BOOL | bTextCompare | |||
) |
Searches for a byte in the TCP RX buffer.
This function finds the first occurrance of a byte in the TCP RX buffer. It can be used by an application to abstract searches out of their own application code. For increased efficiency, the function is capable of limiting the scope of search to a specific range of bytes. It can also perform a case-insensitive search if required.
For example, if the buffer contains "I love PIC MCUs!" and the cFind byte is ' ', a value of 1 will be returned.
hTCP | The socket to search within. | |
cFind | The byte to find in the buffer. | |
wStart | Zero-indexed starting position within the buffer. | |
wSearchLen | Length from wStart to search in the buffer. | |
bTextCompare | TRUE for case-insensitive text search, FALSE for binary search |
0xFFFF | Search array not found | |
Otherwise | Zero-indexed position of the first occurrance |
void TCPFlush | ( | TCP_SOCKET | hTCP | ) |
Immediately transmits all pending TX data.
This function immediately transmits all pending TX data with a PSH flag. If this function is not called, data will automatically be sent when either a) the TX buffer is half full or b) the TCP_AUTO_TRANSMIT_TIMEOUT_VAL (default: 40ms) has elapsed.
hTCP | The socket whose data is to be transmitted. |
BOOL TCPGet | ( | TCP_SOCKET | hTCP, | |
BYTE * | byte | |||
) |
Retrieves a single byte to a TCP socket.
hTCP | The socket from which to read. | |
byte | Pointer to location in which the read byte should be stored. |
TRUE | A byte was read from the buffer. | |
FALSE | The buffer was empty, or the socket is not connected. |
BOOL TCPIsConnected | ( | TCP_SOCKET | hTCP | ) |
Determines if a socket has an established connection.
This function determines if a socket has an established connection to a remote node. Call this function after calling TCPOpen to determine when the connection is set up and ready for use. This function was historically used to check for disconnections, but TCPWasReset is now a more appropriate solution.
hTCP | - The socket to check. |
TRUE | The socket has an established connection to a remote node. | |
FALSE | The socket is not currently connected. |
WORD TCPIsGetReady | ( | TCP_SOCKET | hTCP | ) |
Determines how many bytes can be read from the TCP RX buffer.
Call this function to determine how many bytes can be read from the TCP RX buffer. If this function returns zero, the application must return to the main stack loop before continuing in order to wait for more data to arrive.
hTCP | The socket to check. |
WORD TCPIsPutReady | ( | TCP_SOCKET | hTCP | ) |
Determines how much free space is available in the TCP TX buffer.
Call this function to determine how many bytes can be written to the TCP TX buffer. If this function returns zero, the application must return to the main stack loop before continuing in order to transmit more data.
hTCP | The socket to check. |
TCP_SOCKET TCPOpen | ( | DWORD | dwRemoteHost, | |
BYTE | vRemoteHostType, | |||
WORD | wPort, | |||
BYTE | vSocketPurpose | |||
) |
Opens a TCP socket for listening or as a client.
Provides a unified method for opening TCP sockets. This function can open both client and server sockets. For client sockets, it can accept host name string to query in DNS, and IP address as a string, an IP address in binary form, or a previously resolved NODE_INFO structure. When a host name or IP address only is provided, the TCP module will internally perform the necessary DNS and/or ARP resolution steps before reporting that the TCP socket is connected (via a call to TCPISConnected returning TRUE). Server sockets ignore this destination parameter and listen only on the indicated port.
The vSocketPurpose field allows sockets to be opened with varying buffer size parameters and memory storage mediums. This field corresponds to pre-defined sockets types in TCPIPConfig.h or the TCPIPConfig utility.
Sockets are statically allocated on boot, but can be claimed with this function and freed using TCPDisconnect (for client sockets). Server sockets are opened permanently for the duration of the application. Calls to TCPDisconnect will only release the socket to the listening state.
dwRemoteHost | For client sockets only. Provide a pointer to a null\-terminated string of the remote host name (ex\: "www.microchip.com" or "192.168.1.123"), a literal destination IP address (ex\: 0x7B01A8C0 or an IP_ADDR data type), or a pointer to a NODE_INFO structure with the remote IP address and remote node or gateway MAC address specified. If a string is provided, note that it must be statically allocated in memory and cannot be modified or deallocated until TCPIsConnected returns TRUE. This parameter is ignored for server sockets. | |
vRemoteHostType | TCP_OPEN_SERVER, TCP_OPEN_RAM_HOST, TCP_OPEN_ROM_HOST, TCP_OPEN_IP_ADDRESS, or TCP_OPEN_NODE_INFO. | |
wPort | For client sockets, the remote TCP port to which a connection should be made. For server sockets, the local TCP port on which to listen for connections. | |
vSocketPurpose | Any of the TCP_PURPOSE_* constants defined in TCPIPConfig.h or the TCPIPConfig utility. |
INVALID_SOCKET | No sockets of the specified type were available to be opened. | |
Otherwise | A TCP_SOCKET handle. Save this handle and use it when calling all other TCP APIs. |
// Open a server socket skt = TCPOpen(NULL, TCP_OPEN_SERVER, HTTP_PORT, TCP_PURPOSE_HTTP_SERVER); // Open a client socket to www.microchip.com // The double cast here prevents compiler warnings skt = TCPOpen((DWORD)(PTR_BASE)"www.microchip.com", TCP_OPEN_ROM_HOST, 80, TCP_PURPOSE_DEFAULT); // Reopen a client socket without repeating DNS or ARP SOCKET_INFO cache = TCPGetSocketInfo(skt); // Call with the old socket skt = TCPOpen((DWORD)(PTR_BASE)&cache.remote, TCP_OPEN_NODE_INFO, cache.remotePort.Val, TCP_PURPOSE_DEFAULT);
BOOL TCPPut | ( | TCP_SOCKET | hTCP, | |
BYTE | byte | |||
) |
Writes a single byte to a TCP socket.
hTCP | The socket to which data is to be written. | |
byte | The byte to write. |
TRUE | The byte was written to the transmit buffer. | |
FALSE | The transmit buffer was full, or the socket is not connected. |
WORD TCPPutArray | ( | TCP_SOCKET | hTCP, | |
BYTE * | Data, | |||
WORD | Len | |||
) |
Writes an array from RAM to a TCP socket.
hTCP | The socket to which data is to be written. | |
Data | Pointer to the array to be written. | |
Len | Number of bytes to be written. |
BYTE* TCPPutString | ( | TCP_SOCKET | hTCP, | |
BYTE * | Data | |||
) |
Writes a null-terminated string from RAM to a TCP socket.
The null-terminator is not copied to the socket.
hTCP | The socket to which data is to be written. | |
Data | Pointer to the string to be written. |
BOOL TCPWasReset | ( | TCP_SOCKET | hTCP | ) |
Self-clearing semaphore inidicating socket reset.
This function is a self-clearing semaphore indicating whether or not a socket has been disconnected since the previous call. This function works for all possible disconnections: a call to TCPDisconnect, a FIN from the remote node, or an acknowledgement timeout caused by the loss of a network link. It also returns TRUE after the first call to TCPInit. Applications should use this function to reset their state machines.
This function was added due to the possibility of an error when relying on TCPIsConnected returing FALSE to check for a condition requiring a state machine reset. If a socket is closed (due to a FIN ACK) and then immediately reopened (due to a the arrival of a new SYN) in the same cycle of the stack, calls to TCPIsConnected by the application will never return FALSE even though the socket has been disconnected. This can cause errors for protocols such as HTTP in which a client will immediately open a new connection upon closing of a prior one. Relying on this function instead allows applications to trap those conditions and properly reset their internal state for the new connection.
hTCP | The socket to check. |
TRUE | The socket has been disconnected since the previous call. | |
FALSE | The socket has not been disconnected since the previous call. |