Networking

TCP/UDP

TCP vs UDP

TCP

TCP Rabbit

ACK-Dance

SYN SYN-ACK ACK

Packet Size

Size of Packet

Diff

Drfferences

The 4 Calls

Socket

socket

Bind

bind

Listen

listen

Accept

accept

Connect

connect

Important

Make sure to check errors for every call, networking can fail at any point.

The Gotchas

Network Order

Byte Ordering

Sock Options

Make sure to set socket options to reuse to enable effective debugging of the server. Why does linux do this for sockets?

Signal Handler Safety

Most server applications are interupted through a signal, but you shouldn’t do all of the cleanup in the signal handler because not every function is signal handler safe (think back to CS233). That means the often pattern we see is like below.

int is_running = 1;
int handler(){
	is_running = 0;
}
int main(){
	while(is_running){ /*...*/};

	close(...);
}

Style

Try to modularize your functions so that everything is not in the main method. This is ideally because we need to tell the system that we are done using shared resources like sockets, and we need to determine when a socket goes “out of scope” – we don’t have RAII like in C++ so we have to determine that ourselves.

Nice to Knows

Latency

Latency numbers you should know

Dropped Packets

Why packets get dropped

UDP Example

#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    while(1) {
        printf("Listening on port %s\n", portname);

        ssize_t bytes_recd=recvfrom(fd,buffer,sizeof(buffer),0,(struct sockaddr*)&source,&source_len);
        if (bytes_recd==-1) quit("recvfrom");
        if(bytes_recd == source_len)
            printf("Datagram > buffer - message truncated\n");

        // Print buffer contents
        write(1, buffer, bytes_recd);
        write(1, "\n",1);

        // Encrypt the message
        for(int i=0; i < bytes_recd; i++) {
            if( buffer[i] >= 64) buffer[i] ^= 1;
        }

        int flags = 0;

        size_t bytes_sent = sendto(fd, buffer, bytes_recd, flags, (struct sockaddr*) &source, source_len);
        if(bytes_sent==-1) {
            quit("sendto");
        }

        if(bytes_sent == bytes_recd ) printf("Replied\n");
        else  quit("write");
    }
    return 0;
}