My first mission for Computer Networking is the implementation of the Sliding Window Protocol (SWP) on top of UDP. In a nutshell, the idea is to implement reliable data transmission on top of an unreliable delivery protocol. The program would account for missing, reordered, or duplicate data while delivering non-corrupted data to the user. This functionality is essential for most internet applications and is thus available in TCP. However, understanding of the internal mechanisms of reliable data transmission is essential in a networking class. From what I understand, implementing SWP over UDP is a common assignment for college networking classes.
My textbook provided a skeleton of SWP, and I was provided sample solution binary for both the sender and the receiver. I know a bunch of people have implemented this in the past. So this assignment should be simple, right?
No. At least not for me. More specifically, I crashed spectacularly and burned spectacularly.
Here’s what went wrong:
Waterfall coding– I wrote all 400+ lines of C code… prior to compilation. What happened to all the top-down and the bottom-up coding principles?
Thinking back so far, I don’t believe I had ever written nontrivial code that would take less time to write and test incrementally than it would take in the waterfall method.
In terms of this particular networking assignment, I believe bottom-up is the correct approach. Though this approach, I should be able to separate the networking component and the packet-queuing component via using grammatically correct dummy packets as stubs. I should carefully consider the benefit of bottom-up vs. top-down in the future.
Testing woes– I approached the alien domain of networking without knowing how to test networking code, neither had I planned to do so. Thinking back now, a simple script containing some test cases diffed with some sample outputs could easily saved me hours of backtracking.
No risk mitigation– The networking program requires asynchronous calls through the select call. I read through its documentation thinking that I understood the behavior of the function, and thus wrote all my code expecting select to behave the way I though it did, without testing its functionality at all. When the program is ready for compilation, I could not distinguish between errors caused by select and errors caused by my networking code. After wasting several hours debugging the entire program at once, I decided to test select on its own, which succeeded in less than an hour.
Underestimating complexity– I completely underestimated the potential difficulties of going into areas of programming previously unexplored: in this case, network programming and asynchronous calls. I should have exercised at least twice the caution when approaching these unfamiliar territories, and will do so from now on.
Procrastination– Had I started the program in short segments, I believe I would have avoided most of the problems above, since the incubation periods would likely have led to many of the solutions I had proposed.
During summer, I will likely take up the challenge of doing this homework assignment again, utilizing all that I listed above. Let’s see how second round will go.