Analysis of socket programming in Python

Time:2022-8-12
Table of contents
  • 1. Why use sockets
  • 2. What is a socket
  • 3. How to implement Socket programming in Python
  • 4. What is a server
  • 5. What is a client
    • 5.1、Echo Client-Server
    • 5.2、Multiple Communications
  • 6. Transfer Python objects
    • 6.1. Python pickle module
    • 6.2. How to use pickle module to pass python object structure

1. Why use sockets

Sockets are the foundation of networking. They enable the transfer of information between two different programs or devices. For example, when you open a browser, you as a client are establishing a connection with a server for information transfer.

Before diving into this communication, let's first figure out what exactly these sockets are.

2. What is a socket

In general, sockets are internal endpoints built for sending and receiving data. A single network will have two sockets, one for each communication device or program. These sockets are combinations of IP addresses and ports. Depending on the port number used, a single device can have n slots. Different ports can be used for different types of protocols. Take a look at the images below to learn more about some common port numbers and related protocols:

Now that you understand the concept of sockets, let's take a look at Python's Socket module

3. How to implement Socket programming in Python

To implement Socket programming with Python, you will need to import the socket module or framework. This module consists of built-in methods needed to create sockets and help them associate with each other.

Some important methods are as follows:

Now that you understand the importance of the sockets module, let's move on to see how it creates servers and clients for socket programming in Python.

4. What is a server

A server can be a program, a computer, or a device dedicated to managing network resources. The server can be on the same device or computer, locally connected to other devices and computers, or even remotely. There are various types of servers such as database servers, web servers, print servers, etc.

Servers typically use methods such as socket.socket(), socket.bind(), socket.listen(), etc. to establish connections and bind to clients. Now, let's write a program to create the server. Consider the following example:

example:


import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),1234))          
#port number can be anything between 0-65535(we usually specify non-previleged ports which are > 1023)
s.listen(5)
 
while True:
    clt,adr=s.accept()
    print(f"Connection to {adr}established")  
   #f string is literal string prefixed with f which 
   #contains python expressions inside braces
    clt.send(bytes("Socket Programming in Python","utf-8 ")) #to send info to clientsocket

As you can see, the first necessary condition to create a socket is to import the socket module. After that, use the socket.socket() method to create the server side socket.

NOTE:

AF_INET refers to an address on the Internet, it takes a pair (host, port), where host can be the URL of a particular website or its address, and the port number is an integer. SOCK_STREAM is used to create the TCP protocol.

The bind() method accepts two parameters as a tuple (host, port). However, it is better to use 4-digit port numbers, as smaller port numbers are usually occupied. The listen() method allows the server to accept connections. Here, 5 is the queue of multiple connections appearing at the same time. The minimum value that can be specified here is 0 (change it to 0 if you provide a smaller value). If no parameters are specified, default appropriate parameters are assumed.

The while loop allows accepting connections forever. "clt" and "adr" are client objects and addresses. The print statement just prints out the address and port number of the client socket. Finally, clt.send is used to send byte data.

Now that our server is ready, let's move on to the client.

5. What is a client

A client is a computer or software that receives information or services from a server. In the client server module, the client requests services from the server. The best examples are web browsers such as Google Chrome, Firefox, etc. These web browsers request the desired web pages and services indicated by the user from the web server. Other examples include online games, online chat, etc.

Now let's see how to write a client program in the Python programming language:

example:


import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2346))
msg=s.recv(1024)
print(msg.decode("utf-8"))

The first step is to import the sockets module and then create the socket just like when creating the server. Then, to create a connection between client-server, you need to use the connect() method by specifying (host, port).

Note: gethostname is used when the client and server are on the same computer. (LAN – Local IP / WAN – Public IP)

Here the client wants to receive some information from the server, for this you need to use the recv() method and this information is stored in another variable msg. Remember that the information passed will be in bytes, and in the client of the above program, you can receive up to 1024 bytes (buffer size) in one transfer. Any number can be specified, depending on the amount of information transferred.

Finally, the message being transmitted should be decoded and printed.

Now that you know how to create client-server programs, let's move on to how to execute them.

5.1、Echo Client-Server

To execute these programs, open a command prompt, go to the folder where the client and server programs were created, and type:

py server.py (here, server.py is the filename of the server, you can also use py-3.7 server.py)

Once this is done, the server will start running. To execute the client, open another cmd window and type:

py client.py (here, client.py is the filename of the client)

Output (server):

(client)

Let's try the same program by reducing the buffer size to 7 and see what output we get:
output:

As you can see, the connection is terminated after 7 bytes have been transferred. But this is a problem because you haven't received the full information and the connection is closed. Let's move on to solving this problem.

5.2、Multiple Communications

To keep the connection going until the client receives the complete message, a while loop can be used:

example:


import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2346))
while True:
msg=s.recv(7)
print(msg.decode("utf-8"))

Once this is done, the complete message will be received in 7 bytes per transfer.

But this time, as you can see, the connection doesn't terminate and you don't know when it will happen. Besides that, what if you don't actually know how big the message or information the client will receive from the server. In this case you can actually use the following code on the client side:

example:


complete_info=''
while True:
    msg = s.recv(7)  
    if len(msg)<=0:
        break
    complete_info += msg.decode("utf-8")
print(complete_info)

On the server side, use the close() method as follows:


clt.close()

The output is shown below:

output:

All the code block above does is check the size of the message, print it in a buffer of two bytes at a time, and close it when the connection is complete.

6. Transfer Python objects

Only here you have the trick to transfer strings. However, socket programming in Python also allows you to transfer Python objects. These objects can be sets, tuples, dictionaries, whatever. To achieve this, you will need to import Python's pickle module.

6.1. Python pickle module

The Python pickle module comes when you actually serialize or deserialize objects in python. Let's see a small example,

example:


import pickle
 
mylist=[1,2,'abc']
mymsg = pickle.dumps(mylist) 
print(mymsg)

output:

b’x80x03] qx00(Kx01Kx02Xx03x00x00x00abcqx01e。

As you can see, in the above program, 'mylist' is serialized using the pickle module's dumps() function. Also note that the output starts with a &quot;b&quot; which means it was converted to bytes. In socket programming, this module can be implemented to transfer python objects between client and server.

6.2. How to use pickle module to pass python object structure

When you use pickle with sockets, you can stream absolutely anything over the network. Let's write down the server-side and client-side counterparts to transfer the list from server to client:

Service-Terminal:


import socket
import pickle
 
a=10
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 2133))        #binding tuple
s.listen(5)
while True:
    clt , adr = s.accept()
    print(f"Connection to {adr}established")
 
    m={1:"Client", 2:"Server"}
    mymsg = pickle.dumps(m)  #the msg we want to print later
    mymsg = {len(mymsg):{a}}"utf-8") + mymsg
    clt.send(mymsg)

Here, m is a dictionary which is basically a python object that needs to be sent from the server to the client. This is done by first serializing the object using dumps() and then converting it to bytes. Now let's write down what the client side corresponds to:

Client:


import socket
import pickle
a=10
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 2133))
 
while True:
    complete_info = b''
    rec_msg = True
    while True:
        mymsg = s.recv(10)
       if rec_msg:
            print(f"The length of message = {mymsg[:a]}")
            x = int (mymsg[:a ] )
            rec_msg = False
            complete_info += mymsg
            if len(complete_info)-a == x:
            print("Recieved the complete info")
            print(complete_info[a:])
            m = pickle.loads(complete_info[a:])
            print(m)
            rec_msg = True
complete_info = b''
print(complete_info)

The first while loop will help us keep track of the complete message (complete_info) and the message being received using the buffer (rec_msg). By setting the rec_messages, then, as messages are received, all I do is print each message and receive it in a buffer of size 10. This size can be any value, depending on your personal choice.

Then, if the received message equals the complete message, then I just print the message as the complete message received and then use loads() to deserialize the message. The output of the above program is as follows:

This brings us to the end of this article on programming with Sockets. Hope you understand all concepts clearly.

The above is the detailed content of socket programming in Python. For more information on socket programming in Python, please pay attention to other related articles on developpaer!