运用socket实现简单的ssh功能

  在python socket知识点中已经对socket进行了初步的了解,那现在就使用这些知识来实现一个简单的ssh(Secure Shell)功能。

  首先同样是建立两个端(服务器端和客户端)

  需求是:服务器端需要对客户端发送过来的命令进行相应,并将响应内容返回给客户端。

  看似很简单的需求,但是如何响应命令行?python官方建议buffer的大小不宜超过8k(8192byte),如果返回的数据大于了buffer如何让客户端接收完全?信号传输过程只能通过byte类型,而命令执行过程又需要使用到str,所以在程序中的类型转换也至关重要。

服务器端:

while True:#多用户连接
    conn,addr = server.accept()#等活动开始,accept会返回两个值,conn就是客户端对应在服务器端的连接实例,addr就是客户端链接过来的地址,产生阻塞
    while True:
        print("listened")
        data = conn.recv(1024)#不超过8192,默认是阻塞的,当客户端一断开,会陷入一个死循环,因为客户端会不断的发空""
        if not data:
            print("客户端已断开")
            break
        print('执行指令:',data)
        cmd_os = os.popen(data.decode()).read()#地址为当前所在目录
        cmd_byte = cmd_os.encode('utf-8')
        print('发送长度',len(cmd_byte))
        if len(cmd_os) == 0:#客户端已断开
            cmd_os = "Invalid Command"
        conn.send(str(len(cmd_byte)).encode('utf-8'))#发送第一个:回传长度,判断是否需要循环接收数据
        conn.send(cmd_os.encode('utf-8'))#发送第二个:回传数据,将结果返回给客户端
        print('send done....')
server.close()

客户端:

import socket
client = socket.socket()#声明socket的类型,同时生成socket的连接对象
client.connect(('localhost',6969) )#连接的端口号和端口名
while True:
    msg = input('>>:'.strip())
    if len(msg) == 0:
        continue
    client.send(msg.encode('utf-8'))#需要发送的数据
    print('send',msg)
    data_size = 0#定义收到的数据大小
    recv_data = b''#初始化接收数据
    res_size = client.recv(1024)#接收从服务器端回传的数据大小
    print('the length of res:',res_size.decode())
    while data_size < int(res_size.decode()):#如果数据大小小于回传的数据大小便循环接收
        recv_data+= client.recv(1024)#默认最大接收的字节数
        data_size = len(recv_data)#进行下次循环判定
    else:
        print('the length of recv:',len(recv_data))
        print(recv_data.decode())#打印接收到的数据

client.close()#关闭客户端

  由以上程序,便可实现完整的命令传递以及结果回传。实现简单的ssh功能。

posted @ 2017-08-25 11:42  KeepLearning_!  阅读(1506)  评论(0编辑  收藏  举报