1.缓冲区:
输入缓冲区 输出缓冲区
2. subprocess的使用import subprocess
sub_obj = subprocess.Popen(
'ls', #系统指令
shell=True, #固定
stdout=subprocess.PIPE, #标准输出 PIPE 管道,保存着指令的执行结果
stderr=subprocess.PIPE #标准错误输出
)
print('正确输出',sub_obj.stdout.read().decode('gbk'))
print('错误输出',sub_obj.stderr.read().decode('gbk'))测试byte长度
print(len(b'hello'))
print(bytes(str(2),encoding='utf-8'))
3.两种黏包现象
两种黏包现象:
1 连续的小包可能会被优化算法给组合到一起进行发送
2 第一次如果发送的数据大小2000B接收端一次性接受大小为1024,这就导致剩下的内容会被下一次recv接收到,导致结果错乱
4.粘包现象的解决方案
方案一:由于双方不知道对方发送数据的长度,导致接收的时候,可能接收不全,或者多接收另外一次发送的信息内容,所以在发送真实数据之前,要先发送数据的长度,接收端根据长度来接收后面的真实数据,但是双方有一个交互确认的过程
方案二:
Struct模块,
打包:struct.pack(‘i’,长度)
解包:struct.unpack(‘i’,字节)
第二种服务器端代码
import socket
import subprocess
import struct
server = socket.socket()
ip_port = ('192.168.12.47', 8001)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
while 1:
from_client_cmd = conn.recv(1024)
print(from_client_cmd.decode('utf-8'))
#接收到客户端发送来的系统指令,我服务端通过subprocess模块到服务端自己的系统里面执行这条指令
sub_obj = subprocess.Popen(
from_client_cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE, #正确结果的存放位置
stderr=subprocess.PIPE #错误结果的存放位置
)
#从管道里面拿出结果,通过subprocess.Popen的实例化对象.stdout.read()方法来获取管道中的结果
std_msg = sub_obj.stdout.read()
#为了解决黏包现象,我们统计了一下消息的长度,先将消息的长度发送给客户端,客户端通过这个长度来接收后面我们要发送的真实数据
std_msg_len = len(std_msg)
print('指令的执行结果长度>>>>', len(std_msg))
# pack 打包
msg_lenint_struct = struct.pack('i', std_msg_len)
conn.send(msg_lenint_struct+std_msg)
-------------------------------------------------------
第二种客户端代码import socket
import struct
client = socket.socket()
client.connect(('192.168.12.47', 8001))
while 1:
cmd = input('请输入指令:')
#发送指令
client.send(cmd.encode('utf-8'))
#接收数据长度,首先接收4个字节长度的数据,因为这个4个字节是长 度
#unpack解包因为拿到的是个元组,元组[0]拿出数据
server_res_len = client.recv(4)
msg_len = struct.unpack('i', server_res_len)[0]
print('来自服务端的消息长度', msg_len)
#通过解包出来的长度,来接收后面的真实数据
server_cmd_result = client.recv(msg_len)
print(server_cmd_result.decode('gbk'))
5.struct的使用
import struct
num = 100
#打包,将int类型的数据打包成4个长度的bytes类型的数据
byt = struct.pack('i',num)print(byt)
#解包,将bytes类型的数据,转换为对应的那个int类型的数据
int_num = struct.unpack('i',byt)[0]print(int_num) #(100,)