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 send
or 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 TCP exercise, written by Jean-Martin Vlaeminck, verifies the classical errors that students do when interacting with the TCP socket API.
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.