I'm working on a my own PXE server (so I could install new OS's I want to test easily without the need to find and format USB's). I've stated by examining psychomario/PyPXE project, but quickly implemented my own TFTP Server. I'm testing it agains Intel UNDI PXE-2.1I have on my laptop.
One of the things psychomario doesn't support is sending large files (>32M). The RFC's (1350, 2347) don't discuss how it should be done, but apparently I had two option. The first option, increasing the block size, didn't work since the PXE client apparently ignores fragmented IP packets.
The second option is using rolling block, i.e. starting the counting from the beginning when reaching the end. The client acks the data, but when the data ends, the client starts sending ack's for block 0xffff (even if that's not the last block).
I tried closing the connection and sending empty data packets for that block. The first resulted on error on the PXE, the second resulted in infinite loop with the PXE.
What packet do I need to send in response for the ack of block 0xffff in order to end the session?
1) your TFTP server should really implement the block size option if not you will be limited to 512 byte blocks. Please see RFC 2348. Fragmentation can always be avoided negotiating a blksize such that the whole packet never gets bigger than the minimum MTU (1500 in a typical Ethernet environment).
2) You have to implement a TFTP "roll over"; after sending and getting acked block # = 0xFFFF you should send the next block as block # = 0x0000 and so on until you finish your transfer. When you test this feature be sure to use a TFTP client able to deal with TFTP block roll over; virtually all the PXE clients available today do this very well.
Besides your learning experience coding your own PXE server please consider you will run into countless isuess down the road. If you need to get quick results just google "pxe server" for a list of ready to use PXE server options.