fnSendTCP()

signed short fnSendTCP(USOCKET TCP_socket, unsigned char *ptrBuf, unsigned short usDataLen, unsigned char ucTempFlags);

TCP_socket is the number of the TCP socket over which connection the data should be sent

ptrBuf is a pointer to a buffer containing the data to be sent, whereby the data is situated after space reserved for a TCP header

usDataLen is the length of the TCP payload (the user data)

ucTempFlags contains user specified flags to set to the TCP frame - practically this is TCP_FLAG_PUSH or 0


The routine returns the number of bytes that were transmitted, including the TCP header, IP section and Ethernet II part of the frame. If the transmission was not possible, return values of <= 0 are : This function is called when the user has prepared a buffer containing TCP payload to be transmitted. The buffer much be constructed to allow the routine to add the TCP header to the frame, as is illustrated in the example below (passing a buffer without space for the header may result in data being overwritten and MUST be avoided!. The buffer may not be construced as a const in memory since the routine must be able to write to the TCP header area

The routine can be called at any time from anywhere in project code. It should be used only when there is a TCP/IP connection on the particular TCP socket. When called from within the socket's call back the return value should be set to match the action that was taken. If data was sent, the return value must be set to APP_SENT_DATA. If the attempted TCP transmission failed, for example due to NO_ARP_ENTRY the return value APP_SENT_DATA may not be used - APP_ACCEPT would be correct. A reference to selecting the return value is shown in the example below.

Generally only one TCP frame is transmitted at a time on simple TCP sockets (compare with buffered TCP sockets). Once this frame has been successfully acknowledged by the remote TCP partner the event TCP_EVENT_ACK will be received at the socket's call back routine. Before this has been received, the user must be prepared to be able to repeat the transmission, which means that a backup of the content must be retained or it must be possible to regenerated this content. This can occur due to a timeout (either the transmission was lost or the acknowledge from the remote TCP partner was lost) or the ARP resolution first had to be completed; in both cases the event TCP_EVENT_REGENERATE signals that this must be performed.

The TCP flag TCP_FLAG_PUSH is used by the remote receiver to know whether a block of data (which could be split into a multiple of TCP frames) has been completely received. This has the property of pushing the data which has been collected at the remote TCP partner to its application layer for handling. This means that the push flag is generally set only for the last frame in a block of data. If the complete block of data is contained within the first TCP frame the push flag is set in that single frame. The use of the push flag is however usually not relevant in today's applications.

Note that the TCP transmission doesn't use any TCP options and so the TCP header is of a fixed length.



Example

This example shows a simple TCP server sending data when a connection is made to it. It waits until the data has been acked and then immediately closes the connection. Note that it has a fixed message and so can regenerate this as needed.


static const CHAR cFixedMessage[] = "Hello, World!";

typedef struct stTCP_MESSAGE
{
    TCP_HEADER     tTCP_Header;                                // reserve header space
    unsigned char  ucTCP_Message[(sizeof(cFixedMessage) - 1)]; // data space required by fixed payload
} TCP_MESSAGE;


static int fnListener(USOCKET Socket, unsigned char ucEvent, unsigned char *ucIp_Data, unsigned short usPortLen)
{
    switch (ucEvent) {
    case TCP_EVENT_REGENERATE:
    case TCP_EVENT_CONNECTED:
        {
            TCP_MESSAGE HTTP_Tx;
            uMemcpy(&HTTP_Tx.ucTCP_Message, cFixedMessage, (sizeof(cFixedMessage) - 1)); // prepare payload
            if (fnSendTCP(Socket, (unsigned char *)&HTTP_Tx.tTCP_Header, (sizeof(cFixedMessage) - 1), TCP_FLAG_PUSH) > 0) {
                return APP_SENT_DATA;
            }
        }
        break;
    case TCP_EVENT_ACK:
        fnTCP_close(Socket);
        return APP_REQUEST_CLOSE;          // inform TCP that we have request a close        
    default:
        break;
    }
    return APP_ACCEPT;
}


See the following forum thread for additional details about working with TCP sockets: µTasker forum TCP discussion.

Related functions

fnSendBufTCP();
fnReleaseTCP_Socket();
fnTCP_Listen();
fnGetTCP_state();
fnReportWindow();
fnTCP_Activity();
fnTCP_close();




Please use the µTasker forum to ask specific questions.