Python用socket实现简单的ssh客户端

鳄鱼君

发表文章数:642

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Python用socket实现简单的ssh客户端

我们在Python网络编程socket这篇文章中,已经简单介绍了socket的使用,那么今天的这篇文章,我们就来简单的实现一个ssh客户端,这里可能有小伙伴不知道ssh客户端是做什么的,简单介绍一下:SSH客户端是Windows Phone 7的客户端,可以远程控制服务器,一般就是SecureCRT、Xshell、Putty等等了。

ssh客户端实现

同样需要一个服务器端,和客户端,我们只需要把上篇文章的代码稍微修改一下即可:

server.py

import socket
import os
server=socket.socket()
server.bind(('localhost',9999))
server.listen() #可以接受客户端的数量,一般为5个
print('我要开始等电话了')

conn,addr=server.accept()
print('电话来了',conn)
while True:
    print('准备接受指令了')
    data=conn.recv(1024)
    print('recv:',data)
    cmd=os.popen(data.decode()).read()
    print('没有发送之前指令长度:',len(cmd))
    conn.send(cmd.encode())

    
server.close()

client.py

import socket
client=socket.socket()
client.connect(('localhost',9999))
while True:
    input_content=input('请输入需要执行的指令:').strip()
    if len(input_content)==0:continue
    client.send(input_content.encode())
    data=client.recv(1024) #接受服务器端返回的结果,最多收1024kb,最大不要超过8192kb
    print(data.decode()) 

client.close()

我们在Windows上尝试一下上面的代码,显然是有问题的,我们客户端输入的指令只能是Windows的指令,如果你输入pwd、ls就会报错,这样的指令服务器端也会返回给客户端,只不过是0,然后就会卡死,上面的服务器端我已经添加了接受指令然后发送给客户端的大小,你自己需要不断尝试。

那么卡的原因就在客户端,服务器端接受指令然后从新返回个空值,客户端等不到结果,那么我们可以在服务器端加上判断,如果收到空值,那么我们返回给客户端提示没有这个指令。

server.py

import socket
import os
server=socket.socket()
server.bind(('localhost',9999))
server.listen()
print('我要开始等电话了')

conn,addr=server.accept()
print('电话来了',conn)
while True:
    print('准备接受指令了')
    data=conn.recv(1024)
    print('recv:',data)
    cmd=os.popen(data.decode()).read()
    print('没有发送之前指令长度:',len(data))
    if len(cmd)==0:
        cmd='cmd has not found'
    conn.send(cmd.encode())
    print('发送之后的指令长度:',len(cmd))

server.close()

没有结束,还有一个问题,我们在客户端(client.py)里面收到服务器返回的指令结果的时候,会有文件大小的限制,就是1024kb,比方说我执行ipconfig,然后在执行dir,pwd,你会发现pwd命令返回的是dir没有返回完的结果,也就是我们客户端没有接受完,我们可以把接受的文件大小1024改大一点,但是最大不能超过8192kb,也就是8M,那么我将接收更大的呢,我们可以采用循环接受的方式:

server.py

import socket
import os
server=socket.socket()
server.bind(('localhost',9999))
server.listen()
print('我要开始等电话了')
while True:
    conn,addr=server.accept()
    print('电话来了',conn)
    while True:
        print('准备接受指令了')
        data=conn.recv(1024)
        print('recv:',data)
        cmd=os.popen(data.decode()).read()
        if len(cmd)==0:
            cmd='cmd has not found'
        conn.send(str(len(cmd.encode())).encode()) #把指令的大小发送给客户端,先转换为字节在len
        #confirm=conn.recv(1024) #在插入一次交互,防止粘包
        conn.send(cmd.encode()) 

server.close()

client.py

import socket
client=socket.socket()
client.connect(('localhost',9999))
while True:
    input_content=input('请输入需要执行的指令:').strip()
    if len(input_content)==0:continue
    client.send(input_content.encode())
    data_size=client.recv(1024) #接受指令的大小,字节的总大小
    print('指令的大小为:',data_size)
    #client.send('现在开始发送指令结果...'.encode())
    receive_size=0
    while receive_size < int(data_size.decode()): #最后的指令大小会大于原本的指令大小
        data=client.recv(1024)
        receive_size+=len(data) #每次收到的不一定是1024
        print(receive_size)
    else:
        print(data.decode())
        print('结果已经全部返回....')

client.close()

你在练习的过程中自己多尝试,在Linux和Windows上的效果是不一样的,你也可以把服务器放到Linux上,用Windows的客户端去连接,只不过需要修改bind和connect。

我们可以看到在服务器端,我们先把命令的大小返回给客户端,然后再把命令结果发送过去,如果你在Linux上测试,那么会报错,大致就是粘包的意思吧,两次的数据粘在了一起,再发送个客户端那么肯定会报错,我们可以使用time.sleep(0.5),显然有点不太好,这里不再说这种方法,我们可以等客户端确认一下,在两次发送的中间插入接收,那么不懂的看代码:上面注释掉的部分😏

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Python用socket实现简单的ssh客户端》 发布于2020-01-02

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

7 + 4 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册