Creating a Simple Server from Sockets
5 min read

Creating a Simple Server from Sockets

We'll see how we go from a socket to a simple server, in Python.

What Is a Server?

When you learn web development, you learn to build a server. A server is a program that listens for incoming requests. You probably learned about servers with a web server, which means the communication follows the Hypertext Transfer Protocol.

Not all servers are web servers, nor is all communication done with HTTP. But, all communication is based on sockets. Therefore, both HTTP and web servers are built on top of sockets.

What Is a Socket?

Imagine a computer program like a house; then the door would be the socket. When a house wants to send data to another house, it opens the door and sends it. The other program opens the door to receive the data.

The Transport Layer

What happens between doors is up to the Transport Layer. So the transport layer would be the postman in our metaphor.

IP and Port

How does the transport layer know where to go with the data? To which house? This information is in the data package, and it has two parts: the IP address and the port.

The IP address is a numerical label that identifies a computer in a network (such as 192.0.2.1). What if that computer is running more than one program? How does the computer know to which program the data belongs to?

The port is the program identifier. Once the package reaches the computer, the operating system delivers the data to the specific program based on the port number. The port is displayed commonly after the IP address, separated by a colon: 192.0.2.1:80.

Show Me The Code

We will build and run two different programs that share some information through TCP. TCP is an example of the transport layer mentioned before. We won’t go into the details; it’s enough for us to know that we have a sender (or client) and the receiver (or server) in TCP.

Python Client

This is a simple code in Python to start a connection and send a message as client:

  • We first create a socket with server_socket = socket(AF_INET, SOCK_STREAM).
  • AF_INET indicates the underlying network IPv4
  • SOCK_STREAM means TCP type socket.
  • client_socket.connect(server_id', server_port)) establishes the connection. This is specific to TCP, which needs a handshake between the two programs before sending any data.
  • server_ip and server_port need to be known by the client. We can’t send data to a program if we don’t know where it is.
  • client_socket.send('Hello, server') sends the data. The program puts it out of the door; the OS then sends it through TCP.
  • The program then stops here.
  • client_socket.recv(1024) is called when this program receives something in its socket.
  • client_socket.close() closes the connection.
  • The calls to .decode and .encode are needed because the sockets only care about bytes, not about strings. Calling encode converts the string to bytes, whereas decode converts it back to a string. This is also needed in the server.

Python Server

Let’s now see the code to receive the data:

  • server_socket = socket(AF_INET, SOCK_STREAM) same as before, we create a socket.
  • server_socket.bind(('', server_port)) here we define the port of the program.
  • server_port needs to be the same port the client sends it to. In this case, both have “12000”.
  • server_socket.listen(1) we tell the socket to open the door if something arrives.
  • connection_socket, addr = server_socket.accept(). When a client knocks on the door, the program invokes the accept method, which creates a new socket in the server dedicated to this particular client.
  • The client socket and the new socket complete the TCP handshake, and a new socket is created for this, the connection_socket.
  • data_received = connection_socket.recv(1024). After the handshake, the server receives the data.
  • connection_socket.send("hello from the server!") the new socket replies with some data.
  • connection_socket.close() we close the connection of the newly created socket. Not the server_socket.

Server and Client interaction

Let’s take a look at how the sockets play and connect with each other:

Executing client and server

To execute both programs, we need two terminal windows:

  • One runs the server with python3 server.py.
  • The other executes the client with python3 client.py.

Yet, if we execute the client again, we don’t receive anything. This is because the receiver program has been closed. But, this is not how a server is supposed to work.

Fixing the Server

We don’t want the server program to end. We need to be always open and listen to the door. How do we accomplish this?

I found the answer a little disturbing: “with an infinite loop.”

After receiving data from one client, we want to connect to the next one; therefore, we want to return to connection_socket, addr = server_socket.accept().

The while True: like ensures that this program never ends. Instead, it always comes back at the command server_socket.accept(), which starts the handshake with a client.

This infinite loop converts a simple program that receives data into a server that listens to incoming requests.

From Server to Web Server

Web Servers use the HTTP Protocol to exchange data, and we used sockets to send a simple text through TCP. To build a fully functional HTTP server, we need to implement the protocol both on the client and the server side.

This work is done by many tools and libraries, from fetch in the browser to flask in Python. But, behind those libraries, sockets interact the same way we learned here.

Note the sockets explained here are not Web Sockets. Web Sockets is another protocol used on the internet. Both HTTP and Web Sockets use sockets, the doors of running programs.

Sockets are one of the underlying technologies enabling the internet.

Resources


If you like this post, consider sharing it with your friends on twitter or forwarding this email to them 🙈

Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.

And thanks to Michal and Sebastià for reviewing this article 🙏

Thanks for reading, don't be a stranger 👋

After my development bootcamp 7 years ago I felt lost. Especially at my first job. So many new technologies, processes, concepts to learn.

That's why I write GIMTEC, to help with the topics that you can't learn at work.

Join more than 1,000 subscribers below.

Thanks for subscribing! A confirmation email has been sent.

Check the SPAM folder if you don't receive it shortly.

Sorry, there was an error 🤫.

Try again and contact me at llorenc[at]gimtec.io if it doesn't work. Thanks!