在前面的文章中,介绍过如果使用socket进行客户端与服务端的通信,接下来介绍socketserver模块,可用于多客户端与服务端通信。
由socket模块换成socketserver模块后,改动不大,主要是服务端的代码要进行改动,客户端的代码基本不用动。
服务端要继承BaseRequestHandler类。这个类在初始化的时候,它会依次调用3个方法。子类可以覆盖这些方法。BaseRequestHandler类中的3个方法对应的源码如下:
server端代码:
import socketserver class mySocketServer(socketserver.BaseRequestHandler): def handle(self) -> None: # 每一次请求处理的时候执行 while True: # 接收客户端数据 client_data = str(self.request.recv(1024), encoding="utf-8") print("{} send:".format(self.client_address), client_data) if client_data in ['quit', 'exit']: print("connection lost") break # 发送数据 send_data = input('请输入消息给' + client_data + ':') self.request.sendall(send_data.encode('utf-8')) self.request.close() def setup(self) -> None: # 每一个连接初始化的时候执行 print("before handle,连接建立:", self.client_address) def finish(self): # 每一个连接清理 pass ip_port = ("localhost", 9999) server = socketserver.ThreadingTCPServer(ip_port, mySocketServer) server.serve_forever() #server.handle_request() #只接受一个客户端连接
client端代码:
import socket ip_port = ('127.0.0.1', 9999) # 1、创建socket对象 sk_obj = socket.socket() # 2、连接服务端 sk_obj.connect(ip_port) # 3、发送数据 while True: send_data = input('请输入要发送的数据:') sk_obj.sendall(send_data.encode('utf-8')) # 4、接收服务端数据 server_data = sk_obj.recv(1024).decode('utf-8') if server_data is None or server_data == '': break print("接收到客户端的数据", server_data) # 5、关闭socket sk_obj.close()
可以将client端的代码copy一份,命名为不同的文件名,然后一次启动server,client1,client2的脚本,就可以实现客户端和服务端的通信。并且在代码中加入循环后,就可以实现不停的对话,知道输入exit或者quit指令才会退出通信。
运行效果:
今天先简单介绍一下socket通信的基本操作,至于后面在测开的平台中如何去使用这些技术,敬请期待后面的分享,待我学会了之后继续为大家分享~ 学习过程中遇到问题,可以加V:xiaobotester 一起探讨。