使用struct模块解决黏包问题

 1 ‘‘‘
 2 远程执行cmd命令程序
 3 如果不使用struct模块,ipconfig等会返回长数据的命令会发生黏包现象
 4 ‘‘‘
 5 import socket
 6 import struct
 7
 8 sk = socket.socket()
 9 sk.bind(("127.0.0.1", 8080))
10 sk.listen()
11 conn, addr = sk.accept()
12 while True:
13     cmd = input(">>>")
14     if cmd == "q":
15         conn.send(b"q")
16         break
17     conn.send(bytes(cmd,encoding="gbk"))
18     # windows系统的命令行的编码格式是GBK所以要进行GBK转码
19     num = conn.recv(4)
20     # 接收返回数据的长度
21     num = int(struct.unpack("i",num)[0])
22     # 将接收的bytes类型的struct转换的数字解码,因为返回的是元组所以取元组的第一个,并且下面要用的类型是整数型,转换成int类型
23     print(conn.recv(num).decode("gbk"))
24     # 接收上面传进来大小的数据,解码gbk,打印
25     # 发送多少接收多少就不会产生黏包现象了
26
27 conn.close()
28 sk.close()

server

 1 import socket
 2 import struct
 3 import subprocess
 4
 5 sk = socket.socket()
 6 sk.connect(("127.0.0.1", 8080))
 7 while True:
 8     cmd = sk.recv(1024).decode("gbk")
 9     # Windows命令行是gbk编码,使用gbk解码
10     if cmd == "q":
11         break
12     res = subprocess.Popen(cmd,shell=True,
13                      stdout=subprocess.PIPE,
14                      stderr=subprocess.PIPE)
15     # 使用subprocess模块执行cmd命令
16     # 第一个参数是要执行的命令
17     # shell=True 表示执行的是系统shell命令
18     # stdout 执行成功输出信息,保存到管道
19     # stderr 执行失败输出信息,保存到管道
20     stdout = res.stdout.read()
21     # 读取执行成功信息
22     stderr = res.stderr.read()
23     # 读取执行失败信息
24     str_len = len(stdout)+len(stderr)
25     # 取执行成功和失败信息的长度和
26     num = struct.pack("i",str_len)
27     # 使用struct进行数字固定长度编码
28     # “i” 表示进行转换的是int类型 -> 转换完成后会是固定4字节的bytes类型
29     # 第二个参数是长度数字
30     sk.send(num)
31     # 将长度发送
32     sk.send(stdout)
33     # 发送执行成功信息
34     sk.send(stderr)
35     # 发送执行失败信息
36
37 sk.close()

client

原文地址:https://www.cnblogs.com/changjiangwei/p/11378736.html

时间: 2024-07-31 23:54:14

使用struct模块解决黏包问题的相关文章

struct模块解决黏包问题

client端执行命令 import socket import subprocess import struct sk = socket.socket() sk.connect(('127.0.0.1',8080)) while True: cmd = sk.recv(1024).decode('gbk') if cmd =='q': break res = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE, stderr=subp

网络编程- 解决黏包现象方案一(六)

队列 利用队列的思路来解决黏包问题 总结 原文地址:https://www.cnblogs.com/mys6/p/10797907.html

网络编程- 解决黏包现象方案二之struct模块(七)

server端 import jsonimport structimport socket sk = socket.socket()sk.bind(('127.0.0.1',8080))sk.listen() conn,addr = sk.accept()dic_len = conn.recv(4) # 4个字节 数字的大小dic_len = struct.unpack('i',dic_len)[0]content = conn.recv(dic_len).decode('utf-8') # 7

黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载

黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数据会直接丢失,俗称丢包) #面试 #首先只有在TCP协议中才有黏包现象,是因为TCP协议是面向流的协议, #在发送的数据传输的过程中还有缓存机制来避免数据丢失 #因此在连续发送小数据的时候,以及接收大小不符的时候,都容易产生黏包现象 #本质是不知道客户端发送的数据长度 面试中解释黏包 #连续send

铁乐学Python_Day34_Socket模块2和黏包现象

铁乐学Python_Day34_Socket模块2和黏包现象 套接字 套接字是计算机网络数据结构,它体现了C/S结构中"通信端点"的概念. 在任何类型的通信开始之前,网络应用程序必須创建套接字. 可以将它们比作成电话插孔,没有它将无法进行通信. 套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信. 这就是所谓的进程间通信(Inter Process Communication, IPC). 有两种类型的套接字:基于文件的和面向网

模拟ssh、黏包、hashlib模块

一.模拟ssh 1.subprocess模块 subprocess模块是python从2.4版本开始引入的模块.主要用来取代 一些旧的模块方法,如os.system.os.spawn*.os.popen*.commands.*等.subprocess模块可用于产生进程,并连接到进程的输入/输出/错误输出管道,并获取进程的返回值. import subprocess res = subprocess.Popen("dir", shell=True, stderr=subprocess.P

python tcp黏包和解决方法

一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息. import subprocess sub_obj = subprocess.Popen( 'ls', #系统指令 shell=True, #固定 stdout=subprocess

网络编程中黏包的解决方案

解决方案一 问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据. #_*_coding:utf-8_*_ import socket,subprocess ip_port=('127.0.0.1',8080) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_

网络编程-----黏包问题

一,黏包现象 我们通过一段简单程序来看看黏包现象: import socket sk=socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr=sk.accept() while True: cmd=input(">>>") if cmd=='q': conn.send(b'q') break conn.send(cmd.encode('gbk')) res=conn.recv(1024).de