详解 Python 网络进程
本文旨在介绍 Python 中常用的网络编程模式及其在进程(多进程、多线程)中的应用,以及一些实际场景中的应用示例。
网络编程模式
Python 中关于网络编程的模式较多,其中常用的有以下三种:
TCP 模式
TCP 是一种可靠的、面向连接的传输层协议。它保证数据的可靠性,因为数据会传输到指定的目的地,并且会被确认。TCP 适合用于对可靠传输要求较高的场景,如 HTTP 协议、SMTP 协议、FTP 协议等。
在 Python 中,使用 socket
模块实现 TCP 通信非常简单,示例代码如下:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8000))
server_socket.listen(10)
while True:
client_socket, client_address = server_socket.accept()
print(f"Connection from {client_address[0]}:{client_address[1]}")
data = client_socket.recv(1024)
client_socket.sendall(data)
client_socket.close()
这段代码创建了一个 TCP 服务器,绑定本地地址为 localhost:8000
,并监听最多 10 个客户端的连接。然后服务器进入一个无限循环,接受客户端的连接,并回复客户端请求的数据,最后关闭连接,等待下一个客户端连接。
UDP 模式
UDP 是一种不可靠的、无连接的数据报传输协议。它不保证数据的可靠性,因为数据包会以固定大小的数据包形式发送给接收方。如果其中有数据包丢失,则无法获得原始的数据。UDP 适合用于对实时传输要求较高的场景,如 VoIP 协议、视频通话协议等。
在 Python 中,使用 socket
模块实现 UDP 通信与 TCP 类似,示例代码如下:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('localhost', 8000))
while True:
data, address = server_socket.recvfrom(1024)
print(f"Received data from {address[0]}:{address[1]}")
server_socket.sendto(data, address)
这段代码创建了一个 UDP 服务器,绑定本地地址为 localhost:8000
,然后服务器进入一个无限循环,接收客户端发送的数据,并将数据回复给客户端。
HTTP 模式
HTTP 是一种基于 TCP/UDP 的应用层协议,用于在 Web 浏览器和 Web 服务器之间传输数据。HTTP 协议是一种无状态、无连接、面向文本的协议,以请求(由客户端发起)和响应(由服务器发起)为基础。
在 Python 中,使用 http.server
模块实现简单的 HTTP 服务器非常方便:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
这段代码创建了一个简单的 HTTP 服务器,监听本地的 8000
端口,并等待客户端发起请求。当客户端发来请求时,服务器会返回相应的文件或目录信息。
进程通信
在多进程的环境中,进程间的通信是非常重要的。Python 提供了多种进程间通信的方式,例如:
管道(Pipe)
管道是一种进程间通信的机制,它基于操作系统提供的 FIFO(先进先出)缓冲区。管道可以使用 multiprocessing.Pipe()
函数创建,示例代码如下:
import multiprocessing
def send_message(conn):
conn.send("Hello")
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = multiprocessing.Pipe()
p = multiprocessing.Process(target=send_message, args=(child_conn,))
p.start()
print(parent_conn.recv())
p.join()
这段代码创建了一个进程间的通信管道,然后创建一个子进程,将消息 Hello
发送给父进程,最后在父进程中接收并打印消息。这里的 multiprocessing.Pipe()
函数会返回两个连接对象,一个是发送端连接对象,一个是接收端连接对象,所以需要在父子进程中分别使用不同的连接对象。
队列(Queue)
队列(Queue)是一种进程间通信的机制,它基于操作系统提供的 FIFO(先进先出)缓冲区。队列可以使用 multiprocessing.Queue()
或 queue.Queue()
函数创建,示例代码如下:
import multiprocessing
def send_message(queue):
queue.put("Hello")
if __name__ == '__main__':
queue = multiprocessing.Queue()
p = multiprocessing.Process(target=send_message, args=(queue,))
p.start()
print(queue.get())
p.join()
这段代码创建了一个进程间通信的队列,然后创建一个子进程,将消息 Hello
放入队列中,最后在父进程中从队列中取出消息并打印。
共享内存(Shared Memory)
共享内存是一种进程间通信的机制,它可以将内存区域映射到多个进程的虚拟地址空间中,从而实现多个进程对同一片物理内存区域的共享。共享内存在数据量大、读写频繁的场景下具有很高的效率。
Python 内置的 multiprocessing
模块提供了对共享内存的支持,可以使用 multiprocessing.Value()
和 multiprocessing.Array()
函数创建共享内存对象,示例代码如下:
import multiprocessing
def increment(n):
n.value += 1
if __name__ == '__main__':
num = multiprocessing.Value('i', 0)
p = multiprocessing.Process(target=increment, args=(num,))
p.start()
p.join()
print(num.value)
这段代码创建了一个整型共享内存对象 num
,然后创建一个子进程,将 num
对象的值加一,最后在父进程中打印 num
值。这里的 'i'
参数表示共享内存的数据类型为整型。
示例
下面通过两个例子来说明 Python 网络编程在进程通信方面的应用:
多进程 HTTP 文件服务器
本示例将通过一个多进程实现的 HTTP 文件服务器来演示 TCP、进程通信等技术在实际场景中的应用。
import http.server
import socketserver
import multiprocessing
class FileHTTPServer:
def __init__(self, port=8000):
self.port = port
self.address = ('localhost', port)
def start(self):
handler = http.server.SimpleHTTPRequestHandler
self.server = socketserver.TCPServer(self.address, handler)
self.server.serve_forever()
def stop(self):
self.server.shutdown()
self.server.server_close()
class MultiProcessFileHTTPServer:
def __init__(self, port=8000, process_num=4):
self.process_num = process_num
self.http_server = FileHTTPServer(port=port)
def start(self):
self.processes = []
for i in range(self.process_num):
p = multiprocessing.Process(target=self.http_server.start)
p.daemon = True
p.start()
self.processes.append(p)
def stop(self):
for p in self.processes:
p.terminate()
self.http_server.stop()
if __name__ == '__main__':
server = MultiProcessFileHTTPServer(port=8000, process_num=4)
server.start()
这段代码实现了一个多进程的 HTTP 文件服务器:它由一个主进程和多个子进程构成,每个子进程都运行一个 HTTP 文件服务器。当客户端发送请求时,主进程会从子进程的服务器中选择一个最空闲的进程来处理。
多进程 TCP 服务器
本示例将通过一个多进程实现的 TCP 服务器来演示 TCP、进程通信等技术在实际场景中的应用。
import socket
import multiprocessing
def handle_client(conn, address):
print(f"Connection from {address[0]}:{address[1]}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
conn.close()
class MultiProcessTCPServer:
def __init__(self, host='localhost', port=8000, process_num=4):
self.host = host
self.port = port
self.process_num = process_num
def start(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(10)
self.processes = []
for i in range(self.process_num):
p = multiprocessing.Process(target=self.handle_request)
p.daemon = True
p.start()
self.processes.append(p)
def handle_request(self):
while True:
client_socket, client_address = self.server_socket.accept()
handle_client(client_socket, client_address)
def stop(self):
for p in self.processes:
p.terminate()
self.server_socket.close()
if __name__ == '__main__':
server = MultiProcessTCPServer(process_num=4)
server.start()
这段代码实现了一个多进程的 TCP 服务器:它由一个主进程和多个子进程构成,每个子进程都运行一个 TCP 服务器。当客户端发起连接请求时,主进程会从子进程的服务器中选择一个最空闲的进程来处理。当客户端发送数据时,子进程会接收并处理数据,并将处理结果发送回客户端。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解python网络进程 - Python技术站