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()

 

posted @ 2018-10-12 17:03  greenfan  阅读(325)  评论(0)    收藏  举报