Introduction to Python Network Programming
This tutorial will introduce sockets in Python and how to use the socket module to build HTTP servers and clients in Python. It will also cover Tornado, a Python networking library that is ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.
What is a socket?
A socket is a link between two applications that can communicate with each other (locally on one machine or remotely between two machines in different locations).
Basically, a socket acts as a communication link between two entities, namely the server and the client. The server will give the information requested by the client. For example, when we visited this page, the browser created a socket and connected to the server.
The socket module
To create a socket, we can use socket.socket()
the function, the syntax is very simple:
import socket
s= socket.socket (socket_family, socket_type, protocol=0)
Following is a description of the parameters:
- socket_family : Indicates the address (and protocol) family. It can be AF_UNIX or AF_INET.
- socket_type : Indicates the socket type, which can be SOCK_STREAM or SOCK_DGRAM.
- protocol : This is an optional parameter and usually defaults to 0.
Once we get the socket object, we can create a server or client as per our requirement using methods available in socket module.
Creating a simple client
Before we get started, let's look at the client socket methods available in Python.
-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
s.connect():
Start TCP server connection
To create a new socket, first import the socket method of the socket class.
import socket
Next, we'll create a stream (TCP) socket as follows:
stream_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
AF_INET
The first parameter indicates that we are requesting an Internet Protocol (IP) socket, specifically IPv4. The second parameter is the transport protocol type for a TCP socket SOCK_STREAM
. Additionally, we can AF_INET6
create an IPv6 socket by specifying the socket parameter.
Specify the server.
server = "localhost"
Specify the port we want to communicate with.
port =80
Connect a socket to the port on which the server is listening.
server_address = ((host, port))
stream_socket.connect(server_address)
It is important to note that host and port must be a tuple.
Send data request to the server:
message = 'message'
stream_socket.sendall(message)
Get the response from the server:
data = sock.recv(10)
print(data)
To close a connected socket, we can use close
the method:
stream_socket.close()
Below is the complete code for the client/server.
import socket
# Create a TCP/IP socket
stream_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Define host
host = 'localhost'
# define the communication port
port = 8080
# Connect the socket to the port where the server is listening
server_address = ((host, port))
print("connecting")
stream_socket.connect(server_address)
# Send data
message = 'message'
stream_socket.sendall(message.encode())
# response
data = stream_socket.recv(10)
print(data)
print('socket closed')
Building a simple server
Now let's take a look at a simple Python server. Following are the socket server methods available in Python.
-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
s.bind()
: Bind an address (host name, port number) to a socket. -
s.listen()
: Set up and start a TCP listener. -
s.accept()
: Accept TCP client connections.
We will proceed as follows:
- Create a socket.
- Bind a socket to a port.
- Start accepting connections on the socket.
This is the server program.
import socket
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Define host
host = 'localhost'
# define the communication port
port = 8080
# Bind the socket to the port
sock.bind((host, port))
# Listen for incoming connections
sock.listen(1)
# Wait for a connection
print('waiting for a connection')
connection, client = sock.accept()
print(client, 'connected')
# Receive the data in small chunks and retransmit it
data = connection.recv(16)
print('received "%s"' % data)
if data:
connection.sendall(data)
else:
print('no data from', client)
# Close the connection
connection.close()
The server is now ready to receive incoming connections.
Now run the client and server programs in separate terminal windows so that they can communicate with each other.
Server output
$ python server.py
waiting for a connection
('127.0.0.1', 45504) connected
received "b'message'
Client output
$ python client.py
connecting
b'message'
socket closed
To see which ports are currently in use, you can use netstat -ntlp
the command as shown below.
Tornado Framework
The Tornado framework is one of the libraries available for Python network programming. In this section, we will discuss this library and show how to use it to build a WebSocket.
Tornado is a Python networking framework and asynchronous networking library. Tornado uses non-blocking network I/O and is therefore able to scale to tens of thousands of open connections. This feature makes it ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.
Let's create a simple Tornado WebSocket:
import tornado.ioloop
import tornado.web
class ApplicationHandler(tornado.web.RequestHandler):
def get(self):
self.message = message = """<html>
<head>
<title>Tornado Framework</title>
</head>
<body
<h2>Welcome to the Tornado framework</h2>
</body>
</html>"""
self.write(message)
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", ApplicationHandler),
])
application.listen(5001)
tornado.ioloop.IOLoop.instance().start()
In the code above:
-
We define the class
ApplicationHandler
, which acts as a handler for requests andwrite()
returns responses using the method. - The main method is the entry point of the program.
-
tornado.web.Application
Create a foundation for a web application and adopt a set of handlers, ieApplicationHandler
. - The application listens on port 5000 and clients can communicate with the application using the same port.
-
tornado.ioloop.IOLoop.instance().start()
Create a non-blocking thread for the application.
If we run the application, we will get the result as shown in the following screenshot.
Tornado also integrates the asyncio module, allowing you to use both libraries in the same event loop. Asyncio is a Python library that allows you to write coroutines using async/await syntax.
Synchronous vs. Asynchronous Programming
Synchronous programming is where tasks are completed sequentially. All tasks follow a specific order; meaning each task is completed from start to finish before the next task starts.
One disadvantage of synchronous programming is that if a particular task takes considerable time to execute, subsequent tasks must wait for that task to complete; this can cause delays.
However, asynchronous programming means that tasks can occur simultaneously without waiting for other jobs to finish executing.
Asynchronous communication is mainly used in chat applications and applications that display real-time data.
Asynchronous programming can save time in fetching data from an API. Fetching data from an API or making an HTTP request may take longer than expected; instead of waiting for the http request to complete, you can apply an asynchronous function on the HTTP call. Asynchronous calls free up the program to continue execution in other areas.
Another advantage of asynchronous programming is that if we make multiple requests and one of them stops suddenly, this will not affect the other requests because the program can move on to the next task.
Suppose we have an application that makes multiple requests to an external API server. Using synchronous programming, the application will have to wait until the subsequent API completes the HTTP request and returns a response, slowing down your application.
For example, let's say we want to request an external API, such as a weather API. Let's use Tornado to perform both synchronous and asynchronous calls to get the weather information.
# synchronous function
from tornado.httpclient import HTTPClient
key = 'my_secret_key'
def get_weather():
city = 'london'
url = 'https://api.weatherapi.com/v1/current.json?key='+key+'&q='+city+'&aqi=no'
print(url)
http_client = HTTPClient()
response = http_client.fetch(url)
return (response.body)
# Asynchronous function
from tornado.httpclient import AsyncHTTPClient
secret_key = 'my_secret_key'
async def get_weather():
city = 'london'
url = 'http://api.weatherapi.com/v1/current.json?key='+key+'&q='+city+'&aqi=no'
print(url)
http_client = AsyncHTTPClient()
response = await http_client.fetch(url)
return (response.body)
Summarize
By now, you must have mastered the basics of Python socket programming and how to build simple servers and clients. Feel free to build your own chat client to experiment. For more information, visit the official Python documentation.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Python pandas.pivot_table() 函数
Publish Date:2024/04/24 Views:84 Category:Python
-
Python Pandas pivot_table()函数通过对数据进行汇总,避免了数据的重复。
在 Python 中将 Pandas 系列的日期时间转换为字符串
Publish Date:2024/04/24 Views:904 Category:Python
-
了解如何在 Python 中将 Pandas 系列日期时间转换为字符串
在 Python Pandas 中使用 str.split 将字符串拆分为两个列表列
Publish Date:2024/04/24 Views:1135 Category:Python
-
本教程介绍如何使用 pandas str.split() 函数将字符串拆分为两个列表列。
在 Pandas 中将 Timedelta 转换为 Int
Publish Date:2024/04/23 Views:232 Category:Python
-
可以使用 Pandas 中的 dt 属性将 timedelta 转换为整数。
Python 中的 Pandas 插入方法
Publish Date:2024/04/23 Views:113 Category:Python
-
本教程介绍了如何在 Pandas DataFrame 中使用 insert 方法在 DataFrame 中插入一列。
使用 Python 将 Pandas DataFrame 保存为 HTML
Publish Date:2024/04/21 Views:108 Category:Python
-
本教程演示如何将 Pandas DataFrame 转换为 Python 中的 HTML 表格。
如何将 Python 字典转换为 Pandas DataFrame
Publish Date:2024/04/20 Views:75 Category:Python
-
本教程演示如何将 python 字典转换为 Pandas DataFrame,例如使用 Pandas DataFrame 构造函数或 from_dict 方法。
如何在 Pandas 中将 DataFrame 列转换为日期时间
Publish Date:2024/04/20 Views:101 Category:Python
-
本文介绍如何将 Pandas DataFrame 列转换为 Python 日期时间。