week8-python之socket编程简单模拟ssh执行命令
python3模拟ssh服务
#############################################
用到模块有:socket,subprocess,struct,json,socketserver
实验环境: linux服务器一台 ip:192.168.3.165
window pc一台 ip:192.168.3.10
实现的功能: 1.支持多并发
2.支持常规的回显命令,如cat/ls/date/grep/echo/rm/touch等等
3.支持错误命令报错提示
4.支持大于2G以上的数据流传输
功能不足:不支持交互式命令操作,如:vi tailf等命令
bug:输入交互命令后客户端会卡住,需要强行结束重新连接
################################################
ssh_server.py代码,在python3环境下运行
#!/usr/bin/python3
#__utf8__
#__author:warren
import socket,subprocess,struct,json,socketserver
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
class MyTcphandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
cmd =self.request.recv(1024)
if not cmd: break
res = subprocess.Popen(cmd.decode("utf-8"), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read()
header_dic = {"total_size": len(stdout) + len(stderr), "md5": None}
header_json = json.dumps(header_dic).encode('utf-8')
res = struct.pack('i', len(header_json))
self.request.send(res)
self.request.send(header_json)
self.request.send(stdout)
self.request.send(stderr)
except Exception:
break
server_ssh=socketserver.ThreadingTCPServer(("0.0.0.0",8081),MyTcphandler)
#print("-----ssh start-----")
server_ssh.serve_forever()
client.py代码,在python3环境运行,可跨平台
#__utf-8__
import socket,struct,json
client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('192.168.3.165',8081))
while True:
cmd=input('[localhost]# ').strip()
if not cmd:continue
#发命令
client.send(cmd.encode('utf-8'))
#先收报头的长度
struct_res=client.recv(4)
header_size=struct.unpack('i',struct_res)[0]
#再收报头
header_bytes=client.recv(header_size)
head_json=header_bytes.decode('utf-8')
head_dic=json.loads(head_json)
total_size=head_dic['total_size']
#再收命令的执行结果
recv_size=0
data=b''
while recv_size < total_size:
recv_data=client.recv(1024)
recv_size+=len(recv_data)
data+=recv_data
#打印结果
print(data.decode('utf-8'))
phone.close()
演示:
ssh_sever启动
[root@192-168-3-165 day8]# python3 ssh_server.py & [1] 10842 [root@192-168-3-165 day8]# ps aux |grep ssh_server.py |grep -v grep root 10842 2.0 0.1 145876 7840 pts/1 S 21:55 0:00 python3 ssh_server.py
测试并发:客户端1

测试并发:客户端2

相关详细知识点见下面博客地址:
http://www.cnblogs.com/linhaifeng/articles/6129246.html
单线程ssh服务
#!/usr/bin/python3.4 #__utf8__ import socket,subprocess,struct,json server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) server.bind(("0.0.0.0",8081)) server.listen(5) print("#####server start...#####") while True: conn,client_info=server.accept() print(conn,client_info) while True: try: cmd=conn.recv(1024) if not cmd:break #conn.send(recv_data+".ok".encode("utf-8")) res=subprocess.Popen(cmd.decode("utf-8"),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout=res.stdout.read() stderr=res.stderr.read() # header = struct.pack("ii", len(stdout), len(stderr)) header_dic={"total_size":len(stdout)+len(stderr),"md5":None} header_json=json.dumps(header_dic).encode('utf-8') res=struct.pack('i',len(header_json)) conn.send(res) conn.send(header_json) conn.send(stdout) conn.send(stderr) except Exception: break conn.close() server.close()
sockerserver实现多并发参考
import socketserver class MyTcphandler(socketserver.BaseRequestHandler): def handle(self): while True: #通信循环 data=self.request.recv(1024) self.request.send(data.upper()) if __name__ == '__main__': #取代链接循环 server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcphandler) server.serve_forever()
浙公网安备 33010602011771号