一.缓冲区
缓冲区:将程序和网络解耦(类似于cpu和硬盘需要内存来缓冲一样)
输入缓冲区
输出缓冲区
二.subprocess和struct模块的简单认识
import subprocess
sub_obj = subprocess.Popen(
"dir", # cmd指令
shell=True,
stdout = subprocess.PIPE, #正确的指令存放位置
stderr = subprocess.PIPE # 错误的指令存放位置
)
print(sub_obj.stdout.read().decode("gbk")) # read 拿到的是字节,需要解码(需要解码的字节是系统默认的)
import struct
a = 10
byt = struct.pack("i",a) # 将int类型的a打包成4个字节长度的二进制
a1 = struct.unpack("i",byt) # 将byt解包成一个int类型,返回的是一个元组
三.两种粘包现象(TCP)
1.连续(发送数据间隔短)两个小的数据流会被优化算法给组合到一起并发送,造成粘包
模拟粘包现象服务端
import socket
server = socket.socket()
ip_port = ("127.0.0.1",8888)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
from_client_msg1 = conn.recv(1024)
print(from_client_msg1)
from_client_msg2 = conn.recv(1024)
print(from_client_msg2)
模拟粘包现象客户端
import socket
client = socket.socket()
client.connect(("127.0.0.1",8888))
to_send1 = client.send(b"123")
to_send2 = client.send(b"123")
2.一个大的数据流过大,超过revc的值,那么会一次接收不完,暂时存放在缓冲区,下次再接收的时候就会拿到一六的数据,造成粘包
模拟粘包现象服务端
import socket
import subprocess
server = socket.socket()
ip_port = ("127.0.0.1",8888)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
while 1:
from_client_cmd = conn.recv(1024).decode("utf-8") # 一次只能接收1024b 剩下的存在缓冲区 第二次再接收会粘包
sub_obj = subprocess.Popen(
from_client_cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
to_client_res = sub_obj.stdout.read()
print(len(to_client_res))
conn.send(to_client_res)
模拟粘包现象客户端
import socket
client = socket.socket()
ip_port = ("127.0.0.1",8888)
client.connect(ip_port)
while 1:
cmd = input("请输入cmd指令:").encode("utf-8") # 输入ipconfig -all
client.send(cmd)
server_cmd_res = client.recv(1024).decode("gbk")
print(server_cmd_res)
四.产生粘包的原因及解决方案
1.产生粘包的原因:接收方不知道消息之间的界限,不知道一次性提取多少数据造成的
2.解决粘包现象的方案:自定义一个长度报头
解决粘包现象服务端
import socket
import subprocess
import struct
server = socket.socket()
ip_port = ("127.0.0.1",8888)
server.bind(ip_port)
server.listen()
conn,addr = server.accept()
while 1:
from_client_cmd = conn.recv(1024).decode("utf-8")
sub_obj = subprocess.Popen(
from_client_cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# print(sub_obj.stdout.read())
sub_res = sub_obj.stdout.read()
cmd_len = len(sub_res)
cmd_len_byt = struct.pack("i",cmd_len)
conn.send(cmd_len_byt + sub_res)
解决粘包现象客户端
import socket
import struct
client = socket.socket()
client.connect(("127.0.0.1",8888))
while 1:
cmd = input("请输入cmd指令:").encode("utf-8")
client.send(cmd)
cmd_len_byt = client.recv(4)
cmd_len = struct.unpack("i",cmd_len_byt)[0]
cmd_msg = client.recv(cmd_len).decode("gbk")
print(cmd_msg)