Hi Dean
Congratulations. I will study your code changes in detail since it will be useful to ensure that the solution is generic for small and large chips. This will certainly save me some time on my project too!!
Another suggestion is to use the program memory based error 404 message as uninitialised eeprom would result in a totally blank page.
This restriction is historic and also due to the fact that presently only FLASH or SPI FLASH can be used at the same time. When using SPI FLASH it is only possible to serve pages from there and not to set some to be served out of program flash. That is the reason why the last file block defaults to 404 error file position, but of course requires that the equivalent html file is really loaded there. This is what I will also have to solve in my next project.
but the web page takes about 7 seconds to load
This is a bit longer than I would expect (ensure that there is really no repetition somewhere) but serving large pages is not that fast. The reason is that the HTTP server doesn't send TCP frames using windowing. This is typical for small TCP/IP stacks and has two reasons: firstly it is very simple and reliable; secondly it doesn't need any ram buffers. Using traditional TCP windowing it would be necessary to have several k buffer space for each session - and if say 5 users could access the same web server at the same time this makes 10..15k of RAM, which the small footprint chips have problems to deliver.
First the calculation:
28k will be served in about 28000/1400 frames = 20 where 1400 is the approx. TCP frame payload (check that you have set this (HTTP_BUFFER_LENGTH in app_hw_xxxx.h) since it can be set smaller to save memory on smaller devices (like NE64).
The PC running teh browser will be working with "delayed acks", meaning that it will ack TCP frames after about 200ms delay, in the hope that the application will send data earlier on to which it can 'piggy back' the ACK - this saves sending short frames in some circumstances. Since the Web browser is not sending anything, it results in each ack being delayed by about 200ms and therefore each served frame also being delayed by 200ms.
20x200ms = 4s. I would expect about 4s rather than 7 but this explains basically why it is not that fast. (this is however content specific as well. The dynamic web parser does sometimes have to cut some frames in length if it is not possible to pack in the generated data in the space available).
In the other direction there is no delayed acks in operation and so uploads are (adequately) fast in a LAN.
Typical web pages of only 2k or so are not noticably slow but of course if you have more memory you can afford to have flashy web pages, where this then becomes apparent.
It just turns out... that I also have the same problem with my new project and so my plan is also to add a special windowing technique to the HTTP server where two frames may be sent at once. The TELNET server uses buffered TCP and this does full windowing and achieves fast bulk transfer but it has to have a buffer to work with (its size is defined by TCP_BUFFER in app_hw_xxxx.h). This buffer is absolutely necessary since data is of a random fashion - for example debug outputs from code or data passed from another input like UART. If there were never frames lost it would not be necessary but in order to be able to repeat TCP frames it must have a backup of the data previously sent. In fact most TCP implementations will require a buffer size of twice the data length due to the fact that TELNET can perform byte stuffing if it is operating in ASCII mode which in the worst case doubles the length of the transmitted payload which needs to be backed up. This is not the case in the uTasker since its solution never saves byte stuffed data (which is a bit more complicated) but reduces the maximum buffer space requirement by factor 2.
But back to HTTP... The fact is that once the transmission side actually sends two TCP frames without waiting for the ack of the first, this is already adequate to reset the delayed ack algorithm used at the PC with the browser running on it. Allowing just one outstanding ack is not very difficult and, due to the fact that HTTP served data is essentially static (not of random nature) it is possible to regenerate lost frames without having a buffer, but rather with maybe one or two additional pointers saved in each HTTP session object. My hope is that it will then achieve high speed serving at the cost of only a few bytes RAM and probably a couple of hundred bytes extra program space. Plus the added development complexity until it all works correctly...
I will tell you as soon as there is something ready so that ou can verify its performance.
Regards
Mark