Learning TCP sockets in C
In a previous post, we have described a first INGINIOUS exercise that enables students to check their understanding of the utilisation of the socket API with UDP. This API is more frequently used to interact with TCP. Interacting correctly with TCP is more challenging than interacting correctly with UDP. As TCP provides a reliable, connection-oriented, bystream service, there are several subtleties that the students need to consider to write code that interacts correctly with the TCP socket API.
Besides the classical problem of checking the return values of all system and library calls, including
malloc, but also
receive, students need to correctly understand that TCP provides a bytestream service. A frequent mistake when writing code that interacts with TCP is to assume that any block of data send by the client will be delivered to the server as a block which can be read in a single
recv call. Many students run simple tests in a LAN or through the loopback interface and observe that if that use the
send system call to send
Hello then the other end of the connection will receive
Hello in a single
recv system call. This works most of the time in a LAN, but when sending larger messages in wide area networks, packet losses, retransmissions and other TCP mechanisms may cause TCP to return only a subset of the subset of the data block sent in the first successful
recv call. This implies that students must check the return values of any
recv call and unfortunately many forget to do this.
This exercise is available on https://inginious.org/course/cnp3/sum_of_ints_tcp1 and its source-code has been posted on https://github.com/obonaventure/CNP3-Inginious Feedback is more than welcome on https://github.com/obonaventure/CNP3-Inginious/issues, please indicate sum_of_ints_tcp1 in the title of your issue.