为什么会出现黏包现象:

  首先只有在TCP协议中才会出现黏包现象,是因为TCP协议是面向流的协议,在发送的数据传输的过程中还有缓存机制来避免数据丢失,因此,在连续发送小数据的时候,以及接收大小不符的时候容易出现黏包现象。本质还是因为我们在接收数据的时候不知道发送的数据的长短。

解决黏包问题

  在传输大量数据之前首先告诉接收端要发送的数据大小,如果想更漂亮的解决问题,可以通过struct模块来定制协议。

struct模块:

  功能:可以把一个类型,如数字,转成固定长度的bytes。

import struct

ret = struct.pack('i',456872783)     #'i'代表int,就是即将要把一共数字转换成固定长度(4个字节)的bystes类型
print(ret) num = struct.unpack('i',ret) #转换回来,返回一个元组
print(num[0]) #提前元组中的值得到4096

解决黏包问题:

  服务端:

import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
conn,addr = sk.accept()
while True:
cmd = input('>>>')
if cmd == 'q': #当输入‘q’时,结束,并向客户端发送一个'q'。
conn.send(b'q')
break
conn.send(cmd.encode('gbk')) #将输入的cmd命令发送给客户端
num = conn.recv(4) #接收字节信息(返回的消息长度信息)。
num = struct.unpack('i',num)[0] #将接收的字节码转化为原来的类型并放在一个元组里面,后面加[0]是提前出元组中的值。
res = conn.recv(int(num)).decode('gbk') #接收长度为num 的消息。
print(res) #打印
conn.close()
sk.close()

  客户端:

import struct
import socket
import subprocess sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = sk.recv(1024).decode('gbk') #接收服务端发送来的cmd命令
if cmd == 'q': #当接收到‘q’时,结束。
break
# 在客户端执行接收到的cmd命令。并将正确的消息和错误的消息分别放入stdout和stderr管道。
res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
std_out = res.stdout.read() #读取管道内正确的消息
std_err = res.stderr.read() #读取管道内错误的消息
len_num = len(std_out)+len(std_err) #计算正确和错误消息的总长度
num_by = struct.pack('i',len_num) #将消息总长度转换成长度为4的字节码
sk.send(num_by) #发送消息长度信息
sk.send(std_out) #发送正确消息
sk.send(std_err) #发送错误消息 sk.close()

python_网络编程struct模块解决黏包问题的更多相关文章

  1. Python网络编程基础 struct模块 解决黏包问题 FTP

    struct模块 解决黏包问题 FTP

  2. day29-struct模块解决黏包问题

    #struct模块可以把一个数据类型,例如数字int,转化成固定长度(4个字节)的bytes.int转为4个bytes. #在大量传输数据之前先告诉接收端即将接收数据的大小,方可解决黏包问题: #利用 ...

  3. python_网络编程hmac模块验证客户端的合法性

    hmac模块: 比较两个函数的密钥是否一致: import hmac import os msg = os.urandom(32) #生成32位随机字节码 def wdc(): key = b'wdc ...

  4. python_网络编程socketserver模块实现多用户通信

    服务端: import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): #在这个函数里面 ...

  5. python网络编程基础之socket粘包现象

    粘包现象两种 登陆 #服务端import json import socket server=socket.socket()#创建socket对象 ip_port=('127.0.0.1',8001) ...

  6. python tcp黏包和struct模块解决方法,大文件传输方法及MD5校验

    一.TCP协议 粘包现象 和解决方案 黏包现象让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd)执行远程命令的模块 需要用到模块subprocess sub ...

  7. struct 模块解决 TCP黏包问题

    首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket ​ sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...

  8. python 网络编程--socket模块/struct模块

    socket模块: 客户端:CS架构,  client -> server 浏览器:BS架构,  browser -> server 网络通信本质:传输字节 doc命令查看ip地址:ipc ...

  9. 31_网络编程-struct

    一.struct   1.简述  我们可以借助一个模块,这个模块可以把要发送的数据长度转换成固定长度的字节.这样客户端每次接收消息之前只要先接受这个固定长度字节的内容看一看接下来要接收的信息大小,那么 ...

随机推荐

  1. Dapper存储过程以及多次查询和批量写入操作

    一.存储过程操作 1. 准备存储过程 newsreturnvalue(该存储过程计算2个参数的和并返回) USE [ZPC.Contact] GO SET ANSI_NULLS ON GO SET Q ...

  2. rewrite重写基础实列

    nginx 重写 rewrite 基础及实例 nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大小写匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不 ...

  3. CCF201403 无线网络【限制型最短路】

    问题描述 目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上.任何两个无线路由器只要距离不超过 r 就能互相建立网络连接. 除此以外,另有 m 个可以摆放无线路由器的位置. ...

  4. Java面试题代码篇

    1.统计字符串中的各种字符的个数并对其排序 package JavaMianSiTest; public class TongJIZiFu { public static void main(Stri ...

  5. 【坑】mysql 8.0以后的驱动 jar、连接池的变化

    文章目录 前言 com.mysql.cj.jdbc.Driver 后记 前言 博主公司刚配置了新电脑,安装开发环境的时候,美滋滋的将开发工具都装了新版本,结果在使用 mysql 的时候,发现一直链接数 ...

  6. 剑指offer57:二叉树的下一个结点

    1 题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 2 思路和方法 中序遍历,下一个结点有两种情况 a ...

  7. SAS学习笔记25 t检验(单个样本t检验、配对样本t检验、两个独立样本t检验及方差不齐时的t'检验)

    根据研究设计和资料的性质有单个样本t检验.配对样本t检验.两个独立样本t检验以及在方差不齐时的t'检验 单样本t检验 单样本t检验(one-sample t-test)又称单样本均数t检验,适用于样本 ...

  8. Hibernate之关联关系(一对多)

    今日分享hibernate框架的简单关联关系 一:关联关系简介 1.1 什么是关联关系 关联指的是类之间的引用关系.如果类A与类B关联,那么被引用的类B将被定义为类A的属性. 例如: class B{ ...

  9. linux上启动tomcat报错:Failed to read schema document 'http://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7596118 ,转载请注明出处! spring在加载xsd文件时总是先试图在本地查找xs ...

  10. (九)Hibernate 的复合主键

    一.什么是复合主键? 一张表的主键是由多个字段组成,这个主键就被称为复合主键.  主键是唯一确定某条记录的字段,比如公民的身份证号就是一个主键,因为由身份证号这个主键就可以确定 某个公民.   有一种 ...