Data Science and Machine Learning Internship ...
- 22k Enrolled Learners
- Weekend/Weekday
- Live Class
The Internet has undeniably become the ‘Soul of Existence’ and its activity is characterized by ‘Connections’ or ‘Networks’. These networks are made possible using one of the most crucial fundamentals of Sockets. This article covers all areas dealing with Socket Programming in Python. Sockets help you make these connections, while Python, undoubtedly, makes it easy.
Let’s take a quick look at all the topics covered in this article:
Why use Sockets?
What are Sockets in Python?
How to achieve Socket Programming in Python
What is a server?
What is a client?
Echo Client-Server
Multiple Communications
Transferring Python Objects
To get in-depth knowledge on Python along with its various applications, you can enroll for the best Python course with 24/7 support and lifetime access.
Sockets are the backbone of networking. They make the transfer of information possible between two different programs or devices. For example, when you open up your browser, you as a client are creating a connection to the server for the transfer of information.
Before diving deeper into this communication, let’s first figure out what exactly are these sockets.
In general terms, sockets are interior endpoints built for sending and receiving data. A single network will have two sockets, one for each communicating device or program. These sockets are a combination of an IP address and a Port. A single device can have ‘n’ number of sockets based on the port number that is being used. Different ports are available for different types of protocols. Take a look at the following image for more about some of the common port numbers and the related protocols:
Now that you are clear about the concept of sockets, let’s now take a look at the Socket module of Python:
To achieve Socket Programming in Python, you will need to import the socket module or framework. This module consists of built-in methods that are required for creating sockets and help them associate with each other.
Some of the important methods are as follows:
Methods | Description |
socket.socket() | used to create sockets (required on both server as well as client ends to create sockets) |
socket.accept() | used to accept a connection. It returns a pair of values (conn, address) where conn is a new socket object for sending or receiving data and address is the address of the socket present at the other end of the connection |
socket.bind() | used to bind to the address that is specified as a parameter |
socket.close() | used to mark the socket as closed |
socket.connect() | used to connect to a remote address specified as the parameter |
socket.listen() | enables the server to accept connections |
Now that you have understood the importance of socket module, let’s move on to see how it can serve to create servers and clients for Socket Programming in Python.
A server is either a program, a computer, or a device that is devoted to managing network resources. Servers can either be on the same device or computer or locally connected to other devices and computers or even remote. There are various types of servers such as database servers, network servers, print servers, etc.
Servers commonly make use of methods like socket.socket(), socket.bind(), socket.listen(), etc to establish a connection and bind to the clients. Now let’s write a program to create a 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 necessity to create a socket is to import the socket module. After that the socket.socket() method is used to create a server-side socket.
NOTE:
AF_INET refers to Address from the Internet and it requires a pair of (host, port) where the host can either be a URL of some particular website or its address and the port number is an integer. SOCK_STREAM is used to create TCP Protocols.
The bind() method accepts two parameters as a tuple (host, port). However, it’s better to use 4-digit port numbers as the lower ones are usually occupied. The listen() method allows the server to accept connections. Here, 5 is the queue for multiple connections that come up simultaneously. The minimum value that can be specified here is 0 (If you give a lesser value, it’s changed to 0). In case no parameter is specified, it takes a default suitable one.
The while loop allows accepting connections forever. ‘clt’ and ‘adr’ are the client object and address. The print statement just prints out the address and the port number of the client socket. Finally, clt.send is used to send the data in bytes.
Now that our server is all set, let us move on towards the client.
A client is either a computer or software that receives information or services from the server. In a client-server module, clients requests for services from servers. The best example is a web browser such as Google Chrome, Firefox, etc. These web browsers request web servers for the required web pages and services as directed by the user. Other examples include online games, online chats, etc.
Now let’s take a look at how to code the client-side program in 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 socket module and then create a socket just like you did while creating a server. Then, to create a connection between the client-server you will need to use the connect() method by specifying (host, port).
NOTE: gethostname is used when client and server are on on the same computer. (LAN – localip / WAN – publicip)
Here, the client wants to receive some information from the server and for this, you need to use the recv() method and the information is stored in another variable msg. Just keep in mind that the information being passed will be in bytes and in the client in the above program can receive up to 1024 bytes (buffer size) in a single transfer. It can be specified to any amount depending on the amount of information being transferred.
Finally, the message being transferred should be decoded and printed.
Now that you are aware of how to create client-server programs, let’s move on to see how they need to be executed.
To execute these programs, open up your command prompt, get into the folder where you have created your client and server program and then 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 starts 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 transferring 7 bytes. But this is an issue because you have not received the complete information and the connection is closed. Let’s go on to solve this issue.
For the connection to go on until the client receives the complete information, you can make use of the while loop:
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 you do this, the complete message will be received in 7 bytes per transfer.
But this time, as you can see, the connection does not get terminated and you never know when it’s going to happen. And to add on to this, what if you actually don’t know how big is the message or information that the client will receive from the server. In such cases, you can actually use the following bit of 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 of this will be as shown in the image below:
OUTPUT:
All the above block of code does is, checking the size of the information and printing it in a buffer of two bytes at a time plus closing the connection after it’s completed.
Till here you have just got the knack of transferring strings. But, Socket Programming in Python also allows you to transfer Python objects as well. These objects can be anything like sets, tuples, dictionaries, etc. To achieve this, you will need to import the pickle module of Python.
Python pickle module comes into picture when you are actually serializing or de-serializing objects in python. Let’s take a look at 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 dumps() function of the pickle module. Also make a note that the output starts with a ‘b’, meaning it’s converted to bytes. In socket programming, you can implement this module to transfer python objects between clients and servers.
When you use pickle along with sockets, you can absolutely transfer anything through the network. Let’s write down the server-side and the client-side counterparts to transfer a list from the server to the client:
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 that 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 the client-side counterpart:
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) as well as the message that is being received (rec_msg) using the buffer. the message by setting rec_
Then, while the message is being received, all I am doing is printing each bit of it, being received in a buffer of size 10. This size can be anything depending on your personal choice.
Then, if the message received is equal to the complete message, I’m just printing the message as received complete info following which I have de-serialized the message using loads().
The output to the above program is as follows:
This brings us to the end of this article on Socket Programming in Python. I hope you understood all the concepts clearly.
Got a question for us? Please mention it in the comments section of this “Socket Programming in Python” blog and we will get back to you as soon as possible.
Course Name | Date | Details |
---|---|---|
Data Science with Python Certification Course | Class Starts on 14th December,2024 14th December SAT&SUN (Weekend Batch) | View Details |
edureka.co