前面几节我们写的socket都只能实现服务端与一个客户端通信,并不能实现服务端与多客户端同时通信。接下来我们就来学习一下如何实现服务端同时与多个客户端通信,即并发。
Socket Server
socketserver就是对socket的一个再封装,主要功能就是实现并发。
socketserver模块简化了编写网络服务器的任务。
socketserver一共有以下4种类型:
class socketserver.TCPServer(server_address,RequestHandlerClass,bind_and_activate = True)
它使用Internet TCP协议,该协议在客户端和服务器之间提供连续的数据流。
class socketserver.UDPServer(server_address,RequestHandlerClass,bind_and_activate = True)
它使用数据报,这些数据报是可能无序到达或在传输过程中丢失的离散信息包。参数与TCPServer相同。
class socketserver.UnixStreamServer(server_address,RequestHandlerClass,bind_and_activate = True) class socketserver.UnixDatagramServer(server_address,RequestHandlerClass,bind_and_activate = True)
这些是不经常使用的 类似于TCP和UDP类 的类,但使用Unix域套接字。它们不适用于非Unix平台,参数与TCPServer相同。
如下继承图中有五个类,并且分别显示了他们的继承关系,其中四个代表四种类型的同步服务器:
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
注意:它们都继承了同一个基类:BaseServer。
创建一个 socketserver 至少分以下几步:
1.自己创建一个请求处理类,并且这个类要继承BaseRequestHandler类,并且还要重写父亲类里的handle()方法,此方法将用来处理传入的请求,即跟客户端所有的交互都是在handle()里完成的。
2.实例化一个SocketServer类(4种类型选其1,比如TCPServer),并且传递server address和 你上面创建的请求处理类 给这个SocketServer。
3.调用SocketServer对象的handle_request()或者serve_forever()方法来处理一个或多个请求。
server.handle_request() # 只能处理一个请求,因为处理完一个就退出了,一般不用它
server.serve_forever() # 可处理多个请求,因为永远执行
4.调用server_close()来关闭套接字。
实例1:基本的socketserver代码
import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): """ The request handler class for our server. It is instantiated once per connection to the server, and must override the handle() method to implement communication to the client. """ def handle(self): # self.request is the TCP socket connected to the client self.data = self.request.recv(1024).strip() print("{} wrote:".format(self.client_address[0])) print(self.data) # just send back the same data, but upper-cased self.request.send(self.data.upper()) if __name__ == "__main__": HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999 server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()