SocketServer是对socket的封装和简化。
部分转自:http://www.cnblogs.com/zhangkui/p/5655428.html
1.SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。
注:导入模块的时候 3.x版本是socketserver 2.x版本是SocketServer
1.ThreadingTCPServer
ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。
-
ThreadingTCPServer基础
使用ThreadingTCPServer:
创建一个继承自 SocketServer.BaseRequestHandler 的类
类中必须定义一个名称为 handle 的方法
启动ThreadingTCPServer
服务端
import SocketServer class MyServer(SocketServer.BaseRequestHandler): def handle(self): conn = self.request conn.sendall('我是多线程') Flag = True while Flag: data = conn.recv(1024) if data == 'exit': Flag = False elif data == '0': conn.sendall('您输入的是0') else: conn.sendall('请重新输入.') if __name__ == '__main__': server = SocketServer.ThreadingTCPServer(('127.0.0.1',8009),MyServer) server.serve_forever()
客户端
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket ip_port = ('127.0.0.1',8009) sk = socket.socket() sk.connect(ip_port) while True: data = sk.recv(1024) print 'receive:',data inp = input('please input:') sk.sendall(inp) if inp == 'exit': break sk.close()
内部调用流程为:
- 启动服务端程序
- 执行 TCPServer.init 方法,创建服务端Socket对象并绑定 IP 和 端口
- 执行 BaseServer.init 方法,将自定义的继承自SocketServer.BaseRequestHandler 的类 - MyRequestHandle赋值给 self.RequestHandlerClass
- 执行 BaseServer.server_forever 方法,While 循环一直监听是否有客户端请求到达 ...
当客户端连接到达服务器 - 执行 ThreadingMixIn.process_request 方法,创建一个 “线程” 用来处理请求
- 执行 ThreadingMixIn.process_request_thread 方法
- 执行 BaseServer.finish_request 方法,执行 self.RequestHandlerClass() 即:执行 自定义 MyRequestHandler 的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用 MyRequestHandler的handle方法)
ForkingTCPServer
ForkingTCPServer和ThreadingTCPServer的使用和执行流程基本一致,只不过在内部分别为请求者建立 “线程” 和 “进程”。
实例:
server side
import socketserver class MyTCPHandler(socketserver.BaseRequestHandler): #socketserver必须要继承BaseRequestHandler,每一个客户端请求过来都要实例化class MyTCPHandler def handle(self): #继承完必须重写handle,跟客户端交互都是在handle里面完成的。 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 # Create the server, binding to localhost on port 9999 server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you # interrupt the program with Ctrl-C server.serve_forever()
client side
import socket import sys HOST, PORT = "localhost", 9999 data = " ".join(sys.argv[1:]) # Create a socket (SOCK_STREAM means a TCP socket) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # Connect to server and send data sock.connect((HOST, PORT)) sock.sendall(bytes(data + " ", "utf-8")) # Receive data from the server and shut down received = str(sock.recv(1024), "utf-8") finally: sock.close() print("Sent: {}".format(data)) print("Received: {}".format(received))
1.必须自己创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还有重写父亲类里的handle()
2.必须实例化TCPServer ,并且传递server ip 和 你上面创建的请求处理类 给这个TCPServer
3.server.handle_request() #只处理一个请求
server.serve_forever() #处理多个一个请求,永远执行