It turns out that issue of connection timeout, random protocol data is caused by the fact I did not call the write function after TCP and Ethernet layer processes. The write function is then called in the Ethernet layer (ETH97J60.c). The function that is modified is MACGetArray(). After this modification, there is no more connection timeout problem and random protocol data.
Some corrections and modifications are made to handle the situation when the data retrieved is larger than the remaining block space in the current sector. The process will calculate the number of excess data in bytes, write the first chunk of data into the remaining block space and then send a dummy 16-bit CRC. After that, the data response from the SD card is read and then the SD card is polled until it is no longer busy. After that, a data start token is sent and the remaining data is written into the next sector.
Modifications are also made to handle the situation if the last data byte is sent and the sector is not full written. For this situation, the process will pad the remaining data bytes with 0x00 before proceeding to send a dummy 16-bit CRC, reads the data response and send a data stop token.
After all the mentioned modifications, a 35 KB file upload is completely written in the SD card. But, a 175 KB file and 350 KB file upload are only capable of writing the first 227 sectors of data. My supervisor, Dr. Shawn, suggests that I make sure that the whole file is transferred across the HTTP and also make sure that the whole file is also transferred across the SPI. Using Wireshark, the whole file is seen transferred across the HTTP. By adding a unique character at the end of text file, and performing a byte check before transferring the byte into the SPI shows that the unique character is transferred.
My supervisor then tell me to do a 1 MB multi-block write without involving the HTTP to prove that the multi-block write works. It turns out that my modified functions did not work correctly. Only the first sector is written, and the next few sectors filled with garbage data and the rest of the 1 MB untouched. My modified functions were originally just a single function which will initiates the write, does the writing and closes the writing, but I split it into three because the the TCP socket needs to pause the writing to fetch new data. If I do not call the three functions, instead, calling one single function which will do all of those, all 1 MB of the SD card can be write into successfully using multi-block write.
After some testing and playing around with the functions, it seems some counters is messed up and I have no idea why it was messed up. Particularly the block counter is messed up. The block counter holds count of how many bytes of data is left until the whole block of data is written. If the block counter is messed up, CRC bits, data bytes and commands might all be sending at the wrong time and result in the only the first sector being written. It is stressful since I had no hint on why the counter would be messed up.