socketserver 实现多路复用 例子:远程指令
原生socket只能同时处理一个请求,
多路复用(select、poll、epoll)可以伪并发
socketserver模块可以真正并发处理多个客户端的请求,它内部调用了socket、多路复用和多线程
实现多个客户端可以同时跟服务器发送消息:
服务器端: import socketserver class MyServer(socketserver.BaseRequestHandler): #必须继承这个类 def handle(self): #必须创建名为"handle"的方法,这个方法包含了处理并发功能,self有三个参数,self.request(客户端连接套接字)\self.client_address\self.server con = self.request con.sendall(bytes("welcome to connect me:",encoding = "utf-8")) while True: by = con.recv(1024) st = str(by,encoding = "utf-8") print(st) a = input("me:") con.sendall(bytes(a,encoding = "utf-8")) if __name__ == '__main__': server = socketserver.ThreadingTCPServer(("192.168.0.104",9999),MyServer) server.serve_forever() #这其实是个while循环
客户端:
import socket
obj = socket.socket()
obj.connect(("192.168.0.104",9999,))
ret_bytes = obj.recv(1024)
ret_str = str(ret_bytes,encoding = "utf-8")
print(ret_str) #打印出服务器返回的"welcome to connetc me:"
While True:
inp = input("me:")
obj.sendall(bytes(inp,encoding = "utf-8"))
ret_bytes = obj.recv(1024)
ret_str = str(ret_bytes,encoding = "utf-8")
print(ret_str)
obj.close()
通过客户端连到服务器,执行shell命令,(此例子只能执行那些执行完显示内容的命令,如ls、pwd,不能执行如touch、vim、cd等命令。)
服务器端:
import socketserver
import subprocess
class myserver(socketserver.BaseRequestHandler):
def handle(self):
while True:
conn = self.request
conn.sendall(bytes("welcome..", encoding="utf-8"))
while True:
rev_by = conn.recv(1024)
print(str(rev_by,encoding="utf-8"))
if not rev_by:break
rev_str = str(rev_by,encoding="utf-8")
print(rev_str)
result_str = subprocess.getoutput(rev_str)
result_bytes = bytes(result_str,encoding="utf-8")
print(result_str)
info_str = "info|%d"%len(result_bytes)
conn.sendall(bytes(info_str,encoding="utf-8"))
print(info_str)
conn.sendall(result_bytes)
if __name__ == "__main__":
server = socketserver.ThreadingTCPServer(("127.0.0.1",8008),myserver)
server.serve_forever()
客户端:
import socket
obj = socket.socket()
obj.connect(("127.0.0.1", 8008))
by = obj.recv(1024)
str11 = str(by,encoding="utf-8")
while 1:
inp = input("#")
obj.sendall(bytes(inp,encoding="utf-8"))
byt = obj.recv(1024)
str1 = str(byt,encoding="utf-8")
print("this is str1",str1)
len1 = int(str1.split("|")[1])
print("文件大小:",len1)
has_recv = 0
content_byt = bytes()
while has_recv != len1: #此处可能会出现粘包。所以可以在服务器连续两次发送之间插入一个recv(),相应的客户端也插入一个sendall()
by =obj.recv(1024)
has_recv += len(by)
content_byt += by #content_byt这个变量可以不要,直接让下面端st = str(by,encoding="utf-8")也可以。
st = str(content_byt,encoding="utf-8")
print(st)
obj.close()

浙公网安备 33010602011771号