Basic Tutorial on Network Application Programming in Python 3.5.2

Basic Tutorial on Network Application Programming in Python 3.5.2

Content: This article describes simple network application programming in Python and provides related background knowledge in the field of computer networks.

Time to read: 15 minutes

Audience: Everyone interested in network application programming in Python – beginner level

This article does not cover:

  • Python-specific typography
  • Programming basics (declaration of variables etc.)

In this article I demonstrate socket programming in Python by building a simple “Hello Server!” application. I will keep the code as short and simple as possible. I try to explain every line and some related background in network technology. Python 3.5.2 and the IDLE GUI are used on a Windows 10 machine. Let’s get started.

Network Application Architectures and Transport-Layer Protocols

In this tutorial we build programs in a client/server architecture. The client is the program initiating the connection. The server is waiting for a connection to serve the client. When executed, they both start processes to communicate with each other via sockets.

What are sockets and what are processes? The analogy is that a process is a house and the socket is the door. As programmers we can only influence what happens inside the house. Once we leave the house through the door (socket), we rely on transport-layer protocols for the delivery of our data.

When starting with network application programming, one of the first tasks is to decide which transport-layer protocol we want to use. Herein, I focus on the widespread TCP and UDP. Let’s recall that TCP is connection oriented and ensures that packets arrive at their destination. In contrast, UDP sends packets independently without any guarantees about delivery. Enough of that theory, let’s code.

Network Programming in Python 3.5.2

(OPTIONAL) Step 1: Install Python and run your first script

Install Python and the GUI IDLE on your machine (python.org/downloads/). Start IDLE, go to ‚File‘ -> ‚New File‘ (or Ctrl+N on Windows) and copy paste these lines into the new popped-up window:

import socket

s = socket.gethostbyname(socket.gethostname())

print(s)

Save that file (file extension is .py) and go to ‚Run‘ -> ‚Run Module‘ (or press F5). Voilà! If everything works correctly, IDLE should show your machine’s IP address. If you have any trouble running the code, first validate that you use a similar version of Python (3.5.2 is used herein).You don’t need to understand the code yet. We will cover that later. Right now this task just ensures that everything is set up correctly and works fine. Keep in mind that you have two IDLE instances. In one window you enter all the code and then press F5 to start that module. The results though appear on the initial window. We will stick to that scheme in the following steps, so for every program you have two windows on your screen. Save the IP address as we will need it later.

Edit: Later in this article, in addition to the just retrieved IP address, it is also possible to use the popular localhost address 127.0... As there are problems with publishing the article when the address is completely written out in the LinkedIn editor, I will use localhostAddress instead. This "variable" has to be replaced with the numerical address 127.0... in the code.

Step 2: Server Socket Programming with TCP

Now we are going to program the server side of our application. Start IDLE, create a new file and start programming there. Here is the code:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(('',2050))

s.listen(1)

while 1:

      c, adr = s.accept()

      msg = c.recv(1024)

      print(msg+b' Hello Client!')

      c.close()

In line 1 we are importing the socket module from Python, which allows us to handle network programming.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

Next we create the server socket s. AF_INET indicates an IPv4 address, SOCK_STREAM indicates the TCP protocol.

s.bind(('',2050))

Then we bind that socket to any address (represented by the empty string ' ') and to port number 2050 (try to use non-standardized ports).

s.listen(1)

In line 4 we instruct the socket to listen for incoming connection requests. Parentheses contain the maximum number of connections (1 in this case).

The while-loop lets the server wait for packets.

c, adr = s.accept()

Line 6 invokes the accept() method on the server socket once a client wants to establish a connection. We bind the address details for that connection to a variable adr and open a new dedicated socket for this connection, called c.

msg = c.recv(1024)

The recv() method in line 7 receives data from the socket and stores it in the variable msg. The parameter of recv() indicates the buffer size. For now we set that value to 1024 (later you can experiment here, e.g. set that value to 1 and your server will only receive 1 byte per packet).

print(msg+b' Hello Client!')

c.close()
 

We then simply print the received string and add ‘Hello Client!’. In the last line the socket c is closed. We just programmed a TCP server in 9 lines of code, well done! Let’s create some work for the server to keep it busy.

Step 3: Client Socket Programming with TCP

For the client side start a new IDLE instance and create a new file to enter code (you should now have four IDLE/Python windows on your screen). The client side of our application is even shorter and goes like this:

import socket

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

c.connect(('localhostAddress', 2050))

c.send(b'Hello Server!')

c.close()

As before we have to import the socket-module. Next we create the client socket c similar to the server socket s in the previous step.

c.connect(('localhostAddress', 2050))

We then connect that socket to the server’s name or IP address. You can either use the localhost address localhostAddress (cf. Edit at the end of step 1) or the address determined in step 1 above. Specify the port number the server is listening to (2050 in this case).

c.send(b'Hello Server!')

c.close()

In line 4 we send data to the server (here our simple ‘Hello Server!’ message). Finally the socket is closed.

Step 4: Run the Application

Although we are programming network applications we run the server and the client on the same machine to keep things simple. We do so by connecting with the client to the machine’s own IP address (which is either the localhost address or its IPv4 network address).

Now it’s time to start the server created in step 2. Remember to have two IDLE windows open for that. Run the module where you entered the code and keep watching the results in the other instance. Repeat that procedure for the client side of our small application. As a result you should see the message b'Hello Server! Hello Client!' on the IDLE server side. You just created your first network application, well done!

Step 5: Advanced Scenarios, Tips and Tricks

So far I have suppressed important aspects (like error handling) to keep things as simple as possible. But once you understood the basic principle of network application programming in Python you can add functionality on your own. A good way to start is to add the recv() method known from the server into the client socket code and the client's send() method into the server. For example, you could send a message to the server, add some more text and then send that back to the client. Consider that we are not sending strings as messages but byte objects (indicated by the preceding b). To work with strings you need specific methods like encode() and decode() to convert the received byte objects into string objects. The just discussed principles (server sends data back to client and string de-/encoding) are implemented in the following UDP-based client/server application:

UDP-Server:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind(('',10000))

while 1:

      msg, cAdr = s.recvfrom(2048)

      msg2 = msg.decode().upper().encode()

      s.sendto(msg2, cAdr)

UDP-Client:

import socket

c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

msg = 'Hello World!'

c.sendto(msg.encode(),('localhostAddress', 10000))

msg2, sAdr = c.recvfrom(2048)

print(msg2)

c.close()

Although there are many similarities, notice that for UDP the server just waits for any incoming requests on the specified port. There is no need to ‘listen’ for specific connections. Also notice the change from SOCK_STREAM to SOCK_DGRAM in the socket creation, which indicates UDP.

From here on you are free to play around with these little applications. For example you could use the TCP server from step 2 to print out requests from your browser. To do so, set your browser’s proxy configuration to the IP address of your machine and to the port number the TCP server is listening to (for example, in Firefox v50 go to Settings -> Advanced -> Network tab -> Connection Settings). Then start the TCP server application and enter a website in your browser. The server application prints out the HTTP GET request that your browser issued to retrieve the website.

Finally I would like to explain how to run these small programs more easily. Open the console on your machine (cmd in Windows), browse to the directory where your .py network programs are located and then directly start them from there by typing in the filename (e.g. TCPserver.py). Results are then displayed in the console.

This simple use case closes the article on the basics of network application programming in Python. I hope that you are successfully implementing the examples from above and that you can use them for more advanced and sophisticated applications.

To view or add a comment, sign in

More articles by Tobias Sydekum

Others also viewed

Explore content categories