µTasker Forum > µTasker general
Using TCP in the uTasker project
eduardovra:
Hi Mark!
I working on a project that uTasker will have to work as a protocol converter. A PC will connect (TCP connection) to the board running uTasker and sends some datagrams, then the microcontroler converts them into ethernet raw packets and send to an ASIC chipset that we have. The problem is that some times the TCP datagram sent by the PC application is bigger than the MSS of TCP protocol. In this case, the datagram is divided and sent into two separate packages.
How can I know if the datadram came fragmented and how can I remount them ?
Thanks in advance !
Regards
Eduardo Vieira
mark:
Hi Eduardo
TCP data can arrive at the TCP receiver call-back function as a sequence of several frames. The order in which the frames arrive is always the same as they were sent, but there is no information as to whether the content is a single data packet or a fragment of a larger data packet.
The application which controls the data content can add its own extra information (such as a small header which contains the total length of data which will arrive belonging to a single unity). In this case the receiver call-back handler can know that the data packet has not yet completed (if the present frame length < reported total length). It also knows how much more data is expected before it is complete. I this case it will need to save the data to a local buffer until it is complete - warning: once the call back routine is quit the input data, which is still in the Ethernet reception buffer, will be destroyed (overwritten by subsequent Ethernet receptions). Once the complete data has been received (the buffer used to save it must be adequately large for the largest expected datagram) it can be passed for handling.
Another possible solution (without having to add a header) is if the TCP stack at the PC is using the TCP PUSH flag correctly. The push flag is used to indicate that the present frame is the last in a sequence - it is used to push data to the application, whereas frames received without the PUSH flag set indicate that they first have to be buffered until complete. On the PC the PUSH flag can possibly be controlled by the program sending the data (but you will need to consult the details of the stack used there). It may work automatically but it may not...
The details of the present TCP header is presently not available in the TCP call back routine but this could be easily changed to make the PUSH flag visible (or to pass a different event depending on PUSH flag active or not) if necessary.
Personally I would add a small header to the data content since this will be fully controlable - the PUSH flag operation may change between PC stack implementations and versions so I wouldn't like to have to rely on it.
Regards
Mark
seulater:
can you expound on the static int fnTestListener.
it it set up as a task of its own ? i would imagine that in your example for this it is set up as a task since it is not in a while loop.
mark:
Hi
fnTestListener() is a call-back function and so doen't have any association with tasks in itself.
A call-back function is a routine defined when the socket was opened, which will be called by TCP whenever it has received data or has to report on events (such as connection open or close). It is called directly from the TCP code with a pointer to any data and length of the data.
This means that the call-back is not being scheduled to start as a result of TCP, but instead being called as a sub-routine from TCP. The Ethernet input buffer is thus guarantied to be stable during its processing by the call-back routine. The data is (depending on processor and Ethernet controller details) directly in the Ethernet input buffer ("zero copy" technique as sometimes known as).
Regards
Mark
seulater:
so if things are slowly sinking in, i could create to listening sockets by doing...
USOCKET Test_socket_1 = fnGetTCP_Socket(TOS_MINIMISE_DELAY, (unsigned short)10, fnTestListener_1);
USOCKET Test_socket_2 = fnGetTCP_Socket(TOS_MINIMISE_DELAY, (unsigned short)10, fnTestListener_2);
static unsigned short usTestPort_1 = 10000;
fnTCP_Listen(test_socket_1, usTestPort_1, 0);
static unsigned short usTestPort_2 = 20000;
fnTCP_Listen(test_socket_2, usTestPort_2, 0);
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version