socket大文件传输(解决粘包)

解决粘包
模块struct
      struct.pack(type,num)
          type:是num的类型
          num :是一个数字
          r = struct.pack 把一个数字打包成一个四字节的bytes
      struct.unpack(type,r)
          功能:解包,把r解成原数字,结果是一个元组,原数字在元组的下标位0的位置
#解决粘包:原理是在服务器接收到字典长度后,根据字典长度去recv字典中的内容,就不会造成recv最后一次接收完后剩下的空间留给部分文件内容所造成字典内容和文件内容黏在一起

#实现文件的上传功能
#client层
import socket
import json
import struct
import os

sk=socket.socket()
sk.connect(("10.70.2.143",8080))
option={"1":"upload","2":"download"}
for index,value in option.items():
    print(index,value)
num=input("请输入您的选择")
if num=="1":
    dic={"opt":option.get(num),"filename":None,"filesize":None}
    file_path=input("请输入所需要上传的文件的绝对路径")
    filename=os.path.basename(file_path)
    filesize=os.path.getsize(file_path)
    dic["filename"]=filename
    dic["filesize"]=filesize
    #将字典转为字符串类型
    str_dic=json.dumps(dic)
    #获取字典的长度,为了解决粘包
    len_dic=len(str_dic)
    #解决粘包:原理是在服务器接收到字典长度后,根据字典长度去recv字典中的内容,就不会造成recv最后一次接收完后剩下的空间留给部分文件内容所造成字典内容和文件内容黏在一起
    #用一个4bytes的数据表示字典的长度
    #服务器接收的时候先接收recv(4)个字节长度就可以得到字典的长度
    b_len_dic=struct.pack(‘i‘,len_dic)  #i是原字典长度的数据类型,第二个参数是需要转化的那个字典长度本身
    #将bytes类型的字典长度和字典内容进行拼接并且发送
    sk.send(b_len_dic+str_dic.encode("utf-8"))  #此时字典内容是bytes类型所以可以进行bytes的拼接

    #文件的上传
    with open(file_path,"rb") as f:
        #根据文件大小进行文件的上传
        while filesize:
            content=f.read(1024)
            sk.send(content)
            filesize-=len(content)
else:
    pass
sk.close()

#server层
import socket
import json
import struct

sk=socket.socket()
sk.bind(("10.70.2.143",8080))
sk.listen()
conn,addr=sk.accept()
#先接收从客户端传过来的四个字节长度的字典长度
b_len_dic=conn.recv(4)
#将字节长度的字典长度进行解包成整型的字典长度
len_dic=struct.unpack(‘i‘,b_len_dic)[0] #因为字典长度传过来的是一个元组的第0个下标元素
#根据字典长度去接收字典的内容
#下次进行文件传输的时候就不会造成粘包现象
str_dic=conn.recv(len_dic).decode("utf-8")
#将字符串的字典反序列化成字典
dic=json.loads(str_dic)
if dic["opt"]=="upload":
    #为了防止文件同名,使用字符串拼接文件名进行区分
    filename="1"+dic["filename"]
    #接收从客户端传过来的文件
    with open(filename,"ab") as f:
        #根据文件大小接收数据
        while dic["filesize"]:
            content=conn.recv(1024)
            f.write(content)
            #字典中文件大小减去已接受的文件大小
            dic["filesize"]-=len(content)
elif dic["opt"]=="download":
    pass
conn.close()
sk.close()

原文地址:https://www.cnblogs.com/god-for-speed/p/11719047.html

时间: 2024-12-09 12:35:53

socket大文件传输(解决粘包)的相关文章

Python-socket发送文件并解决粘包问题

服务器端要先根据客户端要下载的文件进行判断是否存在,还要根据文件大小来进行传送,最后还要比对文件的md5值来判断传送的文件是否正确,通过判断剩余字节来解决粘包问题 服务器端 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import socket import os import hashlib server = socket.socket() server.bind(('127.0.0.1',8080)) server.list

粘包产生的原因 socket 基于tcp实现远程执行命令(解决粘包)low

# 粘包产生的原因 # 粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的. # 基于tcp协议的套接字会有粘包现象,而基于udp协议的套接字不会产生粘包现象 # tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住:而udp是基于数据报的,即使你输入的是空内容,那也不是空消息,udp协议会帮你封装上消息头(ip+端口的方式),这样就有了消息办界 # 两种情况下会发生粘包 # 1.发送端需要等缓冲区满才发送

Socket解决粘包问题1

粘包是指发送端发送的包速度过快,到接收端那边多包并成一个包的现象,比如发送端连续10次发送1个字符'a',因为发送的速度很快,接收端可能一次就收到了10个字符'aaaaaaaaaa',这就是接收端的粘包. 可能我们在平时练习时没觉的粘包有什么危害,或者通过把发送端发送的速率调慢来解决粘包,但在实时通信中,发送端常常是单片机或者其他系统的信息采集机,它们的发送速率是无法控制的,如果不解决接收端的粘包问题,我们无法获得正常的信息. 就以我自己正在做的项目来说,接收端是一台单频指标测量仪,它会把当前测

c# socket 解决粘包,半包

处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断是否有剩余字节,有的话缓存起来,循环半包处理 客户端接收代码: private void callReceived(object sender, SocketAsyncEventArgs args) { var socket = sender as Socket; var bb = args.Use

网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

TCP协议:三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立连接的请求 3:客户端接收到服务端发来的请求,返回接成功给服务端,完成双向连接 第一客戶向服务端发送请求,请求建立连接 服务端同客户端的请求,并同时向客户端发送建立 连接的请求,最后客户端同意后建立 双向连接. C ----> S C <---- S - 反馈机制: 客户端往服务端发送请求,服务端必须返回响应, 告诉客户

10.python网络编程(解决粘包问题 part 2)

一.什么时候会产生粘包现象. 只有在使用tcp协议的情况下才会产生粘包现象!udp协议永远不会! 发送端可以1k1k的把数据发送出去,接收端,可以2k2k的的去接收数据,一次可能会接收3k,也有可能1次接收6k. TCP协议是面向流的协议,这也是容易出现粘包问题的原因.而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的.怎样定义消息呢?可以认为对方一次性write/send的数据为一个消息,需要明白的是当对方

Windows下基于TCP协议的大文件传输(流形式)

简单实现TCP下的大文件高效传输 在TCP下进行大文件传输,不像小文件那样直接打包个BUFFER发送出去,因为文件比较大可能是1G,2G或更大,第一效率问题,第二TCP粘包问题.针对服务端的设计来说就更需要严紧些.下面介绍简单地实现大文件在TCP的传输应用. 粘包出现原因:在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows 网络编程) 1 发送端需要等缓冲区满才发送出去,造成粘包 2 接收方不及时接收缓冲区的包,造成多个包接收 解决办法: 为了避免粘包现象,可采取以下几种措

Python网络编程04/recv原理/高大上版解决粘包方式

目录 Python网络编程04/recv原理/高大上版解决粘包方式 1.昨日内容回顾 2.recv工作原理 3.高大上版解决粘包方式(自定制报头) 3.1 解决思路: 3.2 服务端 3.3客户端 4.基于UDP协议的socket通信 4.1服务端 4.2客户端 Python网络编程04/recv原理/高大上版解决粘包方式 1.昨日内容回顾 1. 通信循环 2. 链接通信循环 3. 远程执行命令: subprocess.Popen() # bytes: 网络传输, 文件存储时. 4. 粘包现象

101 解决粘包问题

目录 一.什么是粘包 二.tcp发送数据的四种情况 三.struct模块 四.解决粘包问题 4.1 简单版解决方案 4.1 终极版解决方案(xc版本) 一.什么是粘包 粘包问题是所有语言中都会有的问题,因为只要使用了TCP协议,即使是通过socket编程也都会产生的问题. 注意:只有TCP有粘包现象,UDP永远不会粘包,为何,且听我娓娓道来. 首先需要掌握一个socket收发消息的原理 发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,