Abstract: This article covers all areas related to socket programming with Python. Sockets can help you establish these connections, and Python can undoubtedly simplify connections.
This article is shared from Huawei Cloud Community " Learn Python from scratch | What is socket programming in Python and how to master it? , original author: Yuchuan.
It is undeniable that the Internet has become the "soul of existence", and its activities are characterized by "connections" or "networks." One of the most critical foundations of using sockets makes these networks possible. This article covers all areas related to socket programming with Python. Sockets can help you establish these connections, and Python can undoubtedly simplify connections.
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
- Python pickle module
- How to transfer python objects using the pickle module
Why use Sockets?
Sockets are the foundation of the network. They make it possible to transfer information between two different programs or devices. For example, when you open a browser, you, as a client, are establishing a connection with the server for information transmission.
Before delving into this communication, let us first figure out the exact meaning of these sockets.
What are Sockets?
Generally speaking, a socket is an internal endpoint built for sending and receiving data. A single network will have two sockets, one for each communication device or program. These sockets are a combination of IP address and port. According to the port number used, a single device can have n slots. Different ports can be used for different types of protocols. Please see the following image to learn more about some common port numbers and related protocols:
Now that you have understood the concept of sockets, let's take a look at Python's Socket module:
How to implement Socket programming in Python:
To implement Socket programming using Python, you will need to import a socket module or framework. This module consists of the 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 socket module, let us continue to see how it creates a server and client for socket programming in Python.
What is a server?
The 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, or 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.
The server usually uses methods such as socket.socket(), socket.bind(), socket.listen() to establish a connection and bind to the client. Now, let us 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 necessary condition to create a socket is to import the socket module. After that, use the socket.socket() method to create a server-side socket.
NOTE:
AF_INET refers to an address on the Internet. It needs a pair of (host, port), where the host can be the URL of a specific 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 best to use a 4-digit port number because it usually takes a smaller port number. The listen() method allows the server to accept connections. Here, 5 is a queue of multiple connections that appear at the same time. The minimum value that can be specified here is 0 (if you provide a smaller value, change it to 0). If no parameters are specified, the default appropriate parameters are used.
The while loop allows to accept the connection forever. "Clt" and "adr" are client objects and addresses. The print statement only 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.
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 example is a web browser, such as Google Chrome, Firefox, etc. These web browsers request the required web pages and services indicated by the user from the web server. Other examples include online games, online chats, etc.
Now let's take a look at 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 socket module, and then create the socket, just like when creating the server. Then, to create a connection between the client-server, you need to use the connect() method by specifying (host, port).
Note: When the client and server are on the same computer, gethostname will be used. (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 the information is stored in another variable msg. Remember that the information passed will be in bytes, and in the client of the above program, up to 1024 bytes (buffer size) can be received in one transmission. 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 us continue to see how to execute them.
Echo Client-Server:
To execute these programs, open a command prompt, go to the folder where you created the client and server programs, and type:
py server.py (here, server.py is the file name of the server, you can also use py -3.7 server.py)
After 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 file name 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 transmitted. But this is a problem because you have not received the complete message and the connection has been closed. Let us continue to solve this problem.
Multiple Communications:
In order to make the connection continue 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"))
After completing this operation, each transmission will receive a complete message in the form of 7 bytes.
But this time, as you can see, the connection will not be terminated, and you do not know when the connection will occur. In addition, what if you don't actually know how big the message or information the client will receive from the server is. 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 shown below:
clt.close()
The output is shown below:
Output:
All the work done by the above code block is to check the size of the information and print it in a two-byte buffer at a time, and then close it after the connection is completed.
Transfer Python objects:
Only here do you have the knack for transferring strings. However, socket programming in Python also allows you to transfer Python objects. These objects can be any objects such as collections, tuples, dictionaries, etc. To achieve this, you will need to import Python's pickle module.
Python pickle module:
When you actually serialize or deserialize an object in python, the Python pickle module appears. Let's 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 note that the output starts with "b", which means it has been converted to bytes. In socket programming, this module can be implemented to transfer python objects between the client and the server.
How to pass python object structure using pickle module?
When you use kimchi with sockets, you can definitely transmit anything over the network. Let's write down the server-side and client-side correspondences to transfer the list from the server to the 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 us write down the content corresponding to the client:
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 that is being received using the buffer (rec_msg). Set the message by setting rec_, and then, when receiving a message, all I do is print each message and receive the message in a buffer of size 10. This size can be any value, depending on your personal choice.
Then, if the received message is equal to 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 Socket. Hope you can clearly understand all concepts.
Click to follow and learn about Huawei Cloud's fresh technology for the first time~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。