The TFTP protocol is pretty simple (hence, the “trivial” of TFTP). It’s spelled out in RFC1350 (which is relatively short), but if you just want the quick explanation for a client initiated file read request, it’s as follows:
The server listens on UDP port 69 for incoming requests. When the client wants to read a file, it sends a RRQ (0x0001) followed by a null terminated file name (in ASCII) followed by a null terminated list of “mode” options.The mode options would include either “octect” or “netascii”. I have also seen “blksizeXXXX” to specify the suggested size of the block to send back to the client, and “timeoutX” to indicate the timeout period of the client.
The server hands off to another local UDP port and responds with a DATA packet. This packet is composed of a 16 bit DATA command (value 0x0003) followed by a 16 bit block number followed by the data. The first block should start with a block number of 1.
The client sends an ACK back to the server to indicate receipt of the DATA packet. The ACK packet is composed of a 16 bit ACK command (value 0x0004) followed by the 16 bit block number that it just received.
If the server’s data packet is lost or dropped due to corruption, the server will timeout due to the lack of an ACK from the client and retransmit its last data packet. Receipt of a data packet by the client of size less than the block size will indicate to the client that the transfer is complete.