Python: socket server

The objective of this post is to explain how to create a simple socket server using Python and reach it with a client.


Introduction

The objective of this post is to explain how to create a simple socket server using Python and reach it with a client.

Python is a very easy to use language and thus, as usual, we will be able to setup our server by calling just a few functions.


The code

The first thing we need to do is importing Python’s socket module, which will expose a very easy to use API that will allow us to setup a socket server. This module comes by default with Python and thus the installation of additional packets is not required.

import socket

Next we will create an object of class socket. To do it, we need to call the class constructor, which is defined in the imported socket module.

We will call the no arguments constructor which will use the defaults to create the object, but you can check here the options available and the possible arguments.

s = socket.socket()

Next we need to bind the socket to an address, which will be composed by the IP and the port where the server will be listening.

To do it, we simply need to call the bind method on the socket object we have just created. As input, it will receive a tuple with the IP (as a string) and the port (as a number).

In our case, since we are going to perform the tests in the same machine, we can use the loopback IP 127.0.0.1. I will be using port 8090, but you can try another, as long as it isn’t already in use in your machine.

s.bind(('127.0.0.1', 8090 ))

After performing the binding, we will enable our socket server to start listening to incoming connections. We do it by calling the listen method on the socket object.

This method receives as input the number of unaccepted connections that the system will allow before refusing new connections [1]. Since we are going to do a very simple test with a single client at each time, we can pass it the value 0.

s.listen(0)

Now that we have all the server setup, we start receiving the actual connections by calling the accept method on the socket object. This call will block the execution until a new client connects to the server.

When the client connects, this method returns a pair with a new socket object and the address of the connecting client [2]. This new socket object can be used to send and receive data [2], since sockets are bi-directional.

We will do this call and the remaining client processing in an infinite loop, so we can keep the server working after a client disconnects.

while True:
    client, addr = s.accept()
    #Client handling code

After the previous call we can start exchanging data with the client. In this example, we will simply receive content from him but, as mentioned, sockets are bi-directional and we could also send data to it.

The reception of the data will also be done in an infinite loop, which we will only break when the client disconnects.

To receive data, we simply need to call the recv method on our client socket object (the one returned by the accept method).

In Python 3.x (which is the one I’ve used for this tutorial), the recv method returns the data from the client as a bytes object [3]. However, in Python 2.x, the data is returned as a string [4].

As input, we need to pass to the recv method the maximum number of bytes to be received at once [3]. Note however that if the client sends more data than the value specified, it won’t be lost and can be retrieved with other calls to the recv method.

An important thing to take in consideration is that this recv method call is also blocking. Thus, the execution will block until some data arrives from the client.

If the client disconnects, the recv method will return an empty bytes object, which will be our stopping condition to break the reading loop.

So, after the call to the recv method, we will check for the length of the bytes object. If it is equal to zero, we break the reading the loop. Otherwise, we print the received content.

while True:

    client, addr = s.accept()

    while True:
        content = client.recv(32)

        if len(content) ==0:
           break

        else:
            print(content)

After breaking the reading loop, we call the close method on the client socket object to free the resources.

 client.close()

The final code can be seen below.

import socket

s = socket.socket()         

s.bind(('127.0.0.1', 8090 ))
s.listen(0)                 

while True:

    client, addr = s.accept()

    while True:
        content = client.recv(32)

        if len(content) ==0:
           break

        else:
            print(content)

    print("Closing connection")
    client.close()


Testing the code

To test the code, we could develop a very simple socket client also in Python, which is very easy to do. Nonetheless, to simplify it, we will use our web browser as client to contact the socket server.

So, after running the Python program, open a web browser of your choice and type the following in the address bar (if you haven’t used port 8090, please change this value by yours):

http://127.0.0.1:8090

Your web browser should hang waiting for an answer but if you go back to the Python prompt, you should get an output similar to figure 1, which shows some data getting printed.

Python socket server receive HTTP from browser.png

Figure 1 – Output of the Python program.

The previous figure shows the content that the browser sends to the server when making a HTTP request. This shows that the HTTP protocol that we use everyday to navigate in the Internet is built on top of sockets, which is why we can use a web browser to reach our socket server.

Since our socket server is pretty low level and doesn’t know how work on the HTTP layer, then it won’t return any answer to the browser, which is why it will hang.

If you go back to the browser and close it, then out server should detect it and after freeing the resources it should print the “Closing connection” message, as highlighted in figure 1.

After that, the server should go back to listen to a new connection and you can connect to it again from your web browser.


References

[1] https://docs.python.org/3/library/socket.html#socket.socket.listen

[2] https://docs.python.org/3/library/socket.html#socket.socket.accept

[3] https://docs.python.org/3/library/socket.html#socket.socket.recv

[4] https://docs.python.org/2/library/socket.html#socket.socket.recv

Advertisements
This entry was posted in Python and tagged , , , . Bookmark the permalink.

4 Responses to Python: socket server

  1. ARJ says:

    client.recv(2567) … add .decode(‘utf8’) so that you receive strings

    Liked by 1 person

  2. Pingback: ESP32 Arduino: Sending data with socket client | techtutorialsx

  3. Pingback: ESP32 Arduino Socket server: Getting remote client IP | techtutorialsx

  4. Pingback: ESP32 Socket Server: Connecting from a Putty socket Client | techtutorialsx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s