当前位置:首页 > 编程知识 > 正文

socketserver用法介绍

一、基本介绍

Python提供了标准库socketserver模块,可以方便地实现服务端和客户端socket编程。socketserver模块是使用socket模块开发高级网络服务的简介框架,为Python程序员提供了一个简单易用的服务器框架。socketserver模块中的类继承自Python的标准库Socket模块,包含了常用的网络模式,支持TCP、UDP、Unix socket等多种协议。Server类提供了基本的管理客户端连接、接受和处理请求的方法,继承Server类的各子类则可以自定义处理方式和交互逻辑。

二、TCP服务器

TCP服务器使用TCP协议进行数据传输,提供基于面向连接的高可靠性,支持多用户访问。下面是一个简单的TCP服务器例子:


import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print("{} wrote:".format(self.client_address[0]))
        print(self.data)
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
        server.serve_forever()

该例子中,首先自定义一个处理类MyTCPHandler,继承自socketserver下的RequestHandler类。然后实现handle方法,在其中接受客户端请求和发送响应消息。最后使用TCPServer类创建服务器实例,绑定到本地地址和端口9999,然后开始循环等待客户端请求。如果希望服务器永久运行,可以使用serve_forever方法。

三、UDP服务器

UDP服务器使用UDP协议进行数据传输,提供基于无连接的高效率,支持广播和多点通信。下面是一个简单的UDP服务器例子:


import socketserver

class MyUDPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data, socket = self.request
        print("{} wrote:".format(self.client_address[0]))
        print(data)
        socket.sendto(data.upper(), self.client_address)

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    with socketserver.UDPServer((HOST, PORT), MyUDPHandler) as server:
        server.serve_forever()

该例子中,首先自定义一个处理类MyUDPHandler,继承自socketserver下的RequestHandler类。然后实现handle方法,在其中接受客户端请求和发送响应消息。最后使用UDPServer类创建服务器实例,绑定到本地地址和端口9999,然后开始循环等待客户端请求。如果希望服务器永久运行,可以使用serve_forever方法。

四、Unix Socket服务器

Unix Socket服务器使用Unix Domain Socket进行数据传输,一般用于本地进程之间通信,不需要经过网络。下面是一个简单的Unix Socket服务器例子:


import socketserver

class MyUnixSocketHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print("{} wrote:".format(self.client_address[0]))
        print(self.data)
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    with socketserver.UnixStreamServer("/tmp/mysocket", MyUnixSocketHandler) as server:
        server.serve_forever()

该例子中,首先自定义一个处理类MyUnixSocketHandler,继承自socketserver下的RequestHandler类。然后实现handle方法,在其中接受客户端请求和发送响应消息。最后使用UnixStreamServer类创建服务器实例,绑定到Unix Domain Socket文件"/tmp/mysocket",然后开始循环等待客户端请求。如果希望服务器永久运行,可以使用serve_forever方法。

五、多线程/多进程服务器

如果服务器需要同时处理多个客户端连接,可以使用多线程或多进程将业务逻辑分发到不同的子线程或子进程中处理,提高了服务器的并发性能。下面是一个简单的多线程服务器例子:


import socketserver
import threading

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print("{} wrote:".format(self.client_address[0]))
        print(self.data)
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    with ThreadedTCPServer((HOST, PORT), MyTCPHandler) as server:
        server_thread = threading.Thread(target=server.serve_forever)
        # 单独开一个线程来循环运行服务器实例
        server_thread.daemon = True
        server_thread.start()
        print("Server loop running in thread:", server_thread.name)

该例子中,首先自定义一个ThreadedTCPServer类,继承自socketserver下的ThreadingMixIn和TCPServer类。然后自定义一个处理类MyTCPHandler,继承自socketserver下的BaseRequestHandler类。最后使用ThreadedTCPServer类创建服务器实例,绑定到本地地址和端口9999,然后开一个新的线程来循环运行服务器实例。如果希望服务器永久运行,可以设置单独的线程来运行服务器实例。