学习记录之用
- 准备
- 不用解释啥是【SSH】吧。
- python里可以用commands.getoutput(‘whoami’)获取指令输出结果
derek@ubuntu:~$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import commands
>>> commands.getoutput('whoami')
'derek'
#也可以用commands.getstatusoutput('whoami')
- 为了能多用户用这个【模拟SSH】,这里用到连接池,为此,需要实现类【SocketServer.BaseRequestHandler】重写其方法【handle】。为每一个建立连接的客服端开一个线程,专门为其服务。
class MyTCPServer(SocketServer.BaseRequestHandler):
def handle(self):
pass
- 客户端
import socket
from math import ceil
def recv_all(obj, length):
raw_data=''
for i in range(int(ceil(length/4096.0))):
data=obj.recv(4096)
raw_data+=data
return raw_data
HOST,PORT='192.168.180.128',5200
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
print '---welcome to my ssh---'
while True:
#美化的代码【\033[34;1m \033[0m】在windows下不适用
key=raw_input('\033[34;1mPlease Input Key:\033[0m')
if key == '':
continue
elif key in ['quit','exit']:
break
#发送请求指令
s.sendall(key)
#获取接受的数据的大小
recv_size=int(s.recv(1024))
#由于数据量可能太大,所以分多次接受
recv_data=recv_all(s, recv_size)
print recv_data
s.close()
print 'goodbay(t_t)'
- 服务器端
import SocketServer
import commands, time
class MyTCPServer(SocketServer.BaseRequestHandler):
def handle(self):
#提示建立新连接
print 'Get a new connection from ',self.client_address
#起一个死循环,不断侦听来自客户端的请求
while True:
#接受客户端来的指令
key = self.request.recv(1024).strip()
#接受的数据为空,跳出死循环
if not key:
break
cmd_result = commands.getoutput(key)
#send data_size发送数据大小
self.request.sendall( str(len(cmd_result)) )
#这里是为了防止粘包,是因为底层会把前者小的数据包连着后者一起发送
time.sleep(0.2)
#send raw_data发送原数据
self.request.sendall(cmd_result)
#提示丢失已有连接
print 'Lost connection with ',self.client_address
if __name__=='__main__':
HOST,PORT='192.168.180.128',5200
server=SocketServer.ThreadingTCPServer((HOST,PORT),MyTCPServer)
server.serve_forever()
注意:
服务器端必须要Linux环境下运行
服务器端和客服端需要在同一网段
手机上有一款软件【termux】可以模拟Linux环境,不妨作为客户端测试下