python-- socket 粘包、实现 ssh(python编程)

网友投稿 255 2022-08-25


python-- socket 粘包、实现 ssh(python编程)

粘包

只有tcp协议才会发送粘包,udp不会发生。发送端发送数据,接收端不知道应该如何去接收,造成的一种数据混乱的现象

import subprocessr = subprocess.Popen('ls',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)# subprocess.Popen(cmd,shell=True,subprocess.stdout,subprocess.stderr)# cmd : 代表系统命令# shell = True 代表这条命令是 系统命令,告诉操作系统,将cmd当成系统命令去执行# stdout 是执行完系统命令之后,用于保存结果的一个管道# stderr 是执行完系统命令之后,用于保存错误结果的一个管道stdout = r.stdout.read().decode('gbk')stderr = r.stderr.read().decode('gbk')print('正确的返回结果:',stdout)print('错误的返回结果:',stderr)print('错误的返回结果:',stderr)

客户端发送要执行命令

服务器执行,执行完将结果返回给客户端

客户端拿到结果呈现到用户眼前

服务端

import socketimport subprocesssk = socket.socket()sk.bind(('127.0.0.1', 8080))sk.listen()conn, addr = sk.accept()while 1: cmd = conn.recv(1024).decode('utf-8') r = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = r.stdout.read() stderr = r.stderr.read() if stderr: conn.send(stderr) else: conn.send(stdout)conn.close()sk.close()

客户端

import socketsk = socket.socket()sk.connect_ex(('127.0.0.1', 8080))while 1: cmd = input('请输入一个命令>>>') sk.send(cmd.encode('utf-8')) result = sk.recv(102) result = result.decode('gbk') print(result)sk.close()

socket 实现 ssh

a = '邹'print(len(a)) # 1print(len(a.encode())) # 3 转换为bytes一个汉字三个字符

客户端

import socketclient = socket.socket()client.connect(('localhost', 9999))while True: msg = input(">>:").strip() if len(msg) == 0: # 输入的为空 continue client.send(msg.encode("utf-8")) data = client.recv(1024) print("recv:", data.decode())client.close()

服务端

import socket, osserver = socket.socket()server.bind(('localhost', 9999))server.listen()while True: conn, addr = server.accept() print('new conn', addr) while True: data = conn.recv(1024) if not data: print('客户端已断开') break print('执行指令:', data) cmd_res = os.popen(data.decode()).read() # 执行输入的命令,decode转换为字符串 if len(cmd_res) == 0: cmd_res = 'cmd has no out' conn.send(cmd_res.encode('utf-8')) # 转为utf-8发过去

当我们在客户端执行 ifconfig 命令时,第一次返回的不全(1024字节),在执行 ls 命令时,返回的是 ifconfig 剩下的命令(1024字节),如下

>>:ifconfig=8049 mtu 16384 options=1203 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 nd6 options=201gif0: flags=8010 mtu 1280stf0: flags=0<> mtu 1280ap1: flags=8802 mtu 1500 options=400 ether b2:9c:4a:c4:34:e7 media: autoselect status: inactiveen0: flags=8863 mtu 1500 options=400 ether 90:9c:4a:c4:34:e7 inet6 fe80::18f2:9b2f:4496:675e%en0 prefixlen 64 secured scopeid 0x6 inet 192.168.31.110 netmask 0xffffff00 broadcast 192.168.31.255 nd6 options=201 media: autoselect status: activep2p0: flags=8843 mtu 2304 options=400 ether 02:9c:4a:c4:34:e7 media: autoselect status: inactiveawdl0: flags=8943 mtu 1484 opti>>:ls=400 ether e2:3f:ba:ac:28:1d inet6 fe80::e03f:baff:feac:281d%awdl0 prefixlen 64 scopeid 0x8 nd6 options=201 media: autoselect status: activellw0: flags=8863 mtu 1500 options=400 ether e2:3f:ba:ac:28:1d inet6 fe80::e03f:baff:feac:281d%llw0 prefixlen 64 scopeid 0x9 nd6 options=201 media: autoselect status: activeen2: flags=8963 mtu 1500 options=460 ether 1e:66:6c:14:0d:c4 media: autoselect status: inactiveen1: flags=8963 mtu 1500 options=460 ether 1e:66:6c:14:0d:c5 media: autoselect status: inactiveen3: flags=8963 mtu 1500 options=460 ether 1e:66:6c:14:0d:c1 media: autoselect status: inactiveen4: flags=8963

全部接收

先判断需要接收的数据,然后接收的和实际的对比,如果小于实际的,继续接收,否则,打印出接收的大小和命令

客户端

import socketclient = socket.socket()client.connect(('localhost', 9999))while True: msg = input(">>:").strip() if len(msg) == 0: continue client.send(msg.encode("utf-8")) data_size = client.recv(1024) # 接收命令的长度 print('需要接收的数据大小:', data_size) client.send('开始发吧'.encode('utf-8')) # 处理黏包 reve_size = 0 reve_data = b'' while reve_size < int(data_size.decode()): # data_size是byte类型 data = client.recv(1024) reve_size += len(data) # 每次收到的有可能小于1024,所以必须用len判断 reve_data += data else: print('接收到的大小:', reve_size) print(reve_data.decode())client.close()

服务端

import socket, osserver = socket.socket()server.bind(('localhost', 9999))server.listen()while True: conn, addr = server.accept() print('new conn', addr) while True: print('等待新指令') data = conn.recv(1024) if not data: print('客户端已断开') break print('执行指令:', data) cmd_res = os.popen(data.decode()).read() # 执行输入的命令,decode转换为字符串 print('数据的大小:', len(cmd_res)) if len(cmd_res) == 0: cmd_res = 'cmd has no out' conn.send(str(len(cmd_res.encode())).encode('utf-8')) # 数字不能encode。cmd_res.encode()将汉字转换成3个字节,不转发送的大小和接收的大小不一样 conn.recv(1024) # 处理黏包 conn.send(cmd_res.encode('utf-8')) # 转为 utf-8发过去


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:异常排查记录amqp协议链接陷阱
下一篇:python-- 上传小文件(python和java哪个更值得学)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~