day 8-socket 实现简单的ssh
一、概述
我们用过linux的就知道什么是ssh,它是一种客户端和服务端交互返回的一个解决,输入一个命令,给我返回什么,接下来我们说一说,如何用socket去简单的时间一个ssh
二、简单的ssh
服务器
1 import socket,os 2 3 server=socket.socket() 4 server.bind(("localhost",9999)) 5 server.listen() 6 7 while True: 8 conn,addr = server.accept() 9 print("new conn",addr) 10 11 while True: 12 data =conn.recv(2048) 13 if not data: 14 print("yi duan kai") 15 break 16 17 print("zhi xing zhi ling:",data) 18 cmd_res = os.popen(data.decode()).read() 19 if len(cmd_res) == 0: 20 cmd_res="cmd no output" 21 size=str(len(cmd_res.encode())).encode() 22 conn.send(size) 23 cmd_res=cmd_res.encode() 24 conn.send(cmd_res) 25 26 27 server.close()
客户端:
1 import socket 2 3 client=socket.socket() 4 5 client.connect(("localhost",9999)) 6 7 while True: 8 cmd =input(">>>:").strip() 9 if len(cmd) == 0: continue 10 client.send(cmd.encode()) 11 size=client.recv(2048) 12 13 14 print(size) 15 cmd_data=b'' 16 recv_size=0 17 print(size.decode()) 18 while recv_size < int(size.decode()): 19 cmd_res=client.recv(2048) 20 recv_size+=len(cmd_res) 21 cmd_data+=cmd_res 22 else: 23 cmd_data=cmd_data.decode() 24 print("recv_size",recv_size) 25 print("cmd_data",cmd_data) 26 27 28 client.close()
运行效果:

注意: 这个实验会遇到两个问题,1、计算包大小 。2、数据粘包问题。
1、在python中,str 格式,和byte 格式,中文占的大小不一样。所以 计算大小的时候,统一在 encode 之后计算。
In [11]: a="牛逼" In [12]: len(a) #str 格式一个中文,占一个字符 Out[12]: 2 In [13]: len(a.encode()) #encode 成byte 格式后,大小变成6,一个中文,占3个字符 Out[13]: 6
2、粘包问题,当发送数据包大于一次发送数据包时,
①服务端第一次全部发送给客户端,客户端只接收自己部分的字节数,剩下的字节数被存储在 IO缓冲区 中,下一次你再用send的时候,你以为接收的是新的数据,其实不是,它会先把缓冲区里的数据发出去,然后你的新数据再放到缓冲区中,直到缓冲区满了再发出去
②客户端虽然写的接收的是500,但它不一定能收到500,就是服务器这次send的时候,没有send到500,你依然说你收500,代表着你最多一次只能收500,但是你给我send10个字节,我也得收,所以说它不是等着500全收满了,你发过来多少,我就收多少。

有两种情况缓冲区会给你发数据:
- 缓冲区满了肯定会发
- 缓冲区超时:就是手动send,肯定会给客户端发,这边也已经强制超时了,默认会等着缓冲区慢,手动send是为了不让对方等了,强制发送

浙公网安备 33010602011771号