Programmer's guide to the Computer Networking galaxy

network



From a programmer’s perspective - Computer Networking is not really apart of our job description. As a programmer, your primary role is to write, test, and deploy code. Conduct code reviews, refactor codebases, code, code and code. What we regularly forget is the code we write is solely reliant on Computer Networking. Need to deploy an internal company application? The code is packaged up and sent over the Network. Building a web application? Your code is being served over a Network.

In this post, we will take a birds-eye view over the “bare-minimum” concepts of Computer Networking relevant to the Software community.

RFCs

The internet is a large place and because of this fact, it needs a gate-keeper who lays down the law and tells us exactly how to use the Internet. This is where the Internet Engineering Task Force (IETF) comes to the rescue. They’re an international community who maintains the technical documentation for the Internet. IETF publish technical documentation in the form of Request for Comments (RFCs), which are submitted for community reviews. RFCs are extremely helpful when trying to understand Networking concepts. See for yourself, here is the RFC for the Transmission Control Protocol (TCP), one of the most commonly used Computer Networking protocols used on the internet.

TCP/IP Stack

TCP is just one protocol in the TCP/IP stack. In this stack, there is a whole bunch of protocols. Each protocol is used to communicate differently and achieve different results. What is the TCP/IP stack? It is a model that can be used to establish an end-to-end data communication.
Sending data? Each layer below plays a specific role in getting the data from
point A to point B.

TCP/IP stack

The TCP/IP stack helps to specify how data should be packetized, transmited, routed and received. Therefore, if a request is made to your server for a HTML web page (your website). This will cascade back up to the application layer using Hyper-text Transfer Protocol (HTTP), and your server will receive a GET command. Your web page data is then sent back through your home/work network out through the internet and back to the person requesting to view your web page. Remember, the HTTP protocol only is used to issue a GET command and it does not take care of the transmission of the data packets (the html page). This is up to the below layers to establish the connection from point A to B, then actually get the data packets physically sent out across the internet.

RFC 1122 provides a detailed analysis of each layer of the TCP/IP stack.

Application Layer

So which layer is most useful to a programmer? The Application Layer.
Why? Well for starters, we work in that domain. The programming languages we use to create software, 99% of the time, have networking libraries that we can use to access the application layer protocols.
Want to create a web browser? You’re going to want HTTP methods (GET, POST, PUT etc.).
Want to create an email client? SMTP and POP or IMAP will deliver the core functionality.

Hall of fame

  • Hyper-text Transfer Protocol (HTTP)
  • File Transfer Protocol (FTP)
  • Simple Mail Transfer Protocol (SMTP)
  • Post Office Protocol (POP)
  • Internet Message Access Protocol (IMAP)
  • Domain Name System (DNS)
  • Telnet

These protocols have been, and still are, central to the way our applications communicate on the internet. Most programming language standard libraries publish these protocols to be used by the public. As programmers, we regularly build on top of other software systems, enhancing functionality, and presenting people with fresh, innovative products. No doubt - these protocols can be used to create new and exciting applications for people to use.

The icing on the cake is that the heavy lifting has been done for us. The standard libraries offer easy to use methods and well-written documentation (most of the time). For example, Python’s standard networking library found here. If we look at the HTTP protocol client library, it provides us with an interface to directly build HTTP into our apps. As shown in the code below by simply establishing a HTTP connection to Python’s official website.

1
2
3
import http.client
h1 = http.client.HTTPConnection('www.python.org')

Peer-2-Peer Architecture

Peer-to-peer… is exactly that. It is a network architecture that relies on peers within a network to freely communicate with each other. Peer-to-peer. This is a decentralised network and it does not rely on any one peer (computer) to service the rest of the network. I like to think about peer-to-peer as a social group, where anyone can speak to anyone and exchange information back-and-forth.

We have seen huge innovations of the peer-to-peer architecture, such as BitTorrent, which is a peer-to-peer network application used to exchange data. This was, and still is, widely used for downloading media and large amounts of unstructured data.

A blockchain is another prime example of peer-to-peer network architecture. A blockchain can be used as a distributed ledger, where by each peer communicates with each other to update each peer’s transaction history. The blockchain is the technology behind the bitcoin, a digital cryptocurrency used to purchase items on the internet.

Peer-2-Peer Architecture

Client-Server Architecture

The client-server architecture is an architecture established, whereby a server serves its clients. One server can usually serve many clients, utilising multiprocessing or multithreading solutions. There is only so much clients a server can handle before it needs to divert clients to other running servers. This process is called load balancing.

Take for example, a customer (client) being served by cashier (server) at a gas station…

The server is indeed the single point of failure. If the server goes down, then the clients do not get served. In our gas station sample, for example, if the cashier is not available, then no one can buy fuel. Still with me? See the below diagram showing one server serving multiple clients.

Client-Server Architecture

Socket Programming

Socket programming one of the most useful Networking concepts for a programmer. Let’s first take a look at what actually is a socket. A socket is an open file descriptor used to communicate between a server and the client. The file descriptor is attached to a port number of a host (computer). For example, HTTP occupies port 80, now let’s establish a connection to that port. The client (our computer) would connect to the server to obtain a socket and the server will accept the connection, then return a new socket for the connection. Finally, the server continues to listen on port 80 for more incoming clients. This is how the server can serve multiple clients sending HTTP GET requests.

We can also set up a server on a particular port number to listen for incoming requests. This is really handy if we want to establish a private connection with some clients. Since most packets will be routed through HTTP port 80, we can establish on a random server port 1234. This port is not reserved for common protocols. Here is a list of ports which are reserved.

When the server receives a connection on port 1234, they can then send data to the client/requester. System administrators regularly use socket programming to the monitor ports of their servers. This is to make sure 1. Users are able to access network services and 2. Nothing dodgy is going on, such as port hacking or interference. Here is a quick example of a short program written in Python. It scans the reserved ports of a computer and tells us if they’re either ‘opened’ or ‘closed’.

import socket, threading
host = raw_input("Enter an address to scan: ")
ip = socket.gethostbyname(host)
threads = []
open_ports = {}
def try_port(ip, port, delay, open_ports):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.settimeout(delay)
result = sock.connect_ex((ip, port))
if result == 0:
open_ports[port] = 'open'
return True
else:
open_ports[port] = 'closed'
return None
def scan_ports(ip, delay):
for port in range(0, 1023):
thread = threading.Thread(target=try_port, args=(ip, port, delay
, open_ports))
threads.append(thread)
for i in range(0, 1023):
threads[i].start()
for i in range(0, 1023):
threads[i].join()
for i in range (0, 1023):
if open_ports[i] == 'open':
print '\nport number ' + str(i) + ' is open'
if i == 1022:
print '\nscan complete!'
if __name__ == "__main__":
scan_ports(ip, 3)

Summing up

Together we have covered some fundamentals of the internet, more specifically RFCs and the IETF. We now know that there is more than meets the eye when it comes to data communication and the ability to send data to another computer in the world. This was through the TCP/IP stack, and being aware of the layers below the application layer which help in the process of physically sending the data. And understanding the significance of the application layer when it comes to being a programmer, such as finding out exactly how we can actually make use of these communication protocols. Also, we dived into some popular Networking architecture patterns such as P2P and Client-Server. These are used pretty much everywhere, and they won’t be going away anytime soon. Lastly, we scratched the surface of Network programming by looking into Socket programming and analysing a real-world example to scan port numbers.

It is incredibly interesting diving into the galaxy of Computer Networking! I hope you find this information useful on your programming journey.

Til’ next time.