第一阶段:Python开发基础 day32 网络编程之ssh通信和解决粘包问题
一、简单接收信息
server端:
import socket
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8081))
soc.listen(5)
print('等待客户端链接')
conn,addr = soc.accept()
while True:
info = conn.recv(1024)
print('客户端发送过来的信息:',info)
conn.send(info.upper())
client端:
import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8081))
while True:
msg = input('请输入发送到服务端的信息:')
if msg == 'q':
break
soc.send(msg.encode('utf8'))
info = soc.recv(1024)
print('服务端发送回来的消息:',info)
二、网络编程构建ssh通信
import socket
import subprocess
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print('等待客户端链接')
soc.bind(('127.0.0.1',8081))
soc.listen(5)
conn, addr = soc.accept()
print('客户端已连接',addr)
while True:
while True:
cmd = conn.recv(1024) # 接收客户端传过来的cmd指令
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE
)
stdout = pipeline.stdout.read()
conn.send(stdout)
client端:
import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8081))
while True:
msg = input('input cmd:')
soc.send(msg.encode('utf8'))
data = soc.recv(1024)
print(data.decode('gbk'))
三、解决粘包问题
server端:
import socket
import subprocess
import json
import struct
soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(('127.0.0.1',8081))
soc.listen(5)
while True:
print('等待客户端链接')
conn, addr = soc.accept()
print('客户端已连接', addr)
while True:
try:
cmd = conn.recv(1024) # 接收客户端传过来的cmd指令
if len(cmd) == 0:
break
pipeline = subprocess.Popen(cmd.decode('utf8'),
shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE
)
msg = pipeline.stdout.read() # 我们实际上要传的东西
head = {'size':len(msg)} # 自定义一个报头,用于存放我们实际要传的内容的长度
print(head)
# 为了该报头能传送,需要序列化并且转为bytes
head_bytes = (json.dumps(head)).encode('utf8') #序列化并转成bytes,用于传输
# 为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
head_bytes_len = struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度
# 处理完数据之后,可以开始向客户端发送数据了
print(head_bytes_len)
conn.send(head_bytes_len) # 发送头长度
conn.send(head_bytes) # 发送头内容
conn.send(msg) # 发送了实际内容
except Exception:
break
conn.close()
client端:
import socket
import struct
import json
soc = socket.socket()
soc.connect(('127.0.0.1',8081))
while True:
msg = input('input cmd:')
soc.send(msg.encode('utf8'))
head_bytes_len = soc.recv(4) # 拿到struct后的头长度
head_len = struct.unpack('i',head_bytes_len)[0] # 取出真正的头长度
print(head_len)
# 拿到真正的头部内容
head_bytes = soc.recv(head_len)
# 反序列化后取出头
head = json.loads(head_bytes)
# head头是一个字典,这样我们就可以取出真正要传输的内容的长度
msg_len = head['size']
msg = b''
while msg_len > 1024:
msg += soc.recv(1024)
msg_len -= 1024
else:
msg += soc.recv(msg_len)
print(str(msg,encoding='gbk'))