Python Socket 模拟SSH

6 篇文章 0 订阅
1 篇文章 0 订阅

学习记录之用

- 准备

  • 不用解释啥是【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环境,不妨作为客户端测试下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值