python socket传输大文件的方法

2023-10-31

×××××××××××××方法一:

	发送端
1、计算发送文件大小,然后结合文件的其他信息,组成文件头先发送一次。
2、发送文件数据时用sendall(),一次发送所有数据(好像是重复调用了send())
	接收端
1、接收端根据接受文件的大小和recv_size计算要接收数据的次数,
2、然后把每次接收的数据连在一起
3、因为可能不是整除,最后要判断下最后一次具体接收多少字节数据(感觉也可以不用这样,直接接收)

1、计算文件大小

1、os.path.getsize(filepath)
2、os.stat(filepath).st_size

2、socket接收数据的操作的注意事项

因为下面的原因,我们要在接收端接收头文件时做一些处理,用来与数据文件区分

#服务器
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",8000))
server.listen(3)
while True:
    sock,adddr = server.accept()
    data = sock.recv(1024)
    print(data.decode("utf8")+"\n")
    if(data.decode("utf8") == "111"):
        print("dsfaf")
        server.close()
sock.close()
#客户端
import socket 
import json
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",8000))
header_data = {
    'file_size': 1000299,
}
client.send(json.dumps(header_data).encode("utf-8"))
client.send("ripo".encode("utf8"))
client.send("fasdf".encode("utf8"))
client.send("oiposfdpakf".encode("utf8"))
client.send("111".encode("utf8"))
client.close()

服务器输出结果

{"file_size": 1000299}ripofasdfoiposfdpakf111

可见虽然客户端是用多个send函数发送的,服务器采用1024大小的缓冲(sock.recv(1024))区,一次把所有数据的都接收了。这样就不能区分出我们先发送的文件头和文件内容了。

解决方案

1、使用send和recv隔离

在发送端第一次发送数据,也就是发送文件头信息的时候,接收端在接收后在给发送端发送一个数据,
然后发送端接收后(不必处理),相当于在发送文件头信息和文件信息之间加了一步,这样接收端就能区
分开了。

2、(推荐):使用struct计算头文件大小

使用struct库
1、首先在发送端和接收端约定一个fmt,也就是头文件的格式。
2、客户端 
	struct.pack(fmt,v1,v2.....)
3、服务器端
(1)struct.calcsize(fmt),可以计算大小,这样就可以在接收端接收指定大小的数据。这个大小对应头
文件数据的大小。
(2)struct.unpack(fmt,v1,v2.....)

第一种方法最终代码:

#服务器端
import socket
import struct
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",3008))
server.listen(3)
while True:
    print("start.......")
    sock,adddr = server.accept()
    d = sock.recv(struct.calcsize("l"))
    total_size = struct.unpack("l",d)
    num  = total_size[0]//1024
    data = b''
    for i in range(num):
        data += sock.recv(1024)
    data += sock.recv(total_size[0]%1024)

    with open("11.png","wb") as f:
        f.write(data)
    sock.close()
sock.close()
#客户端
import socket 
import struct
import os
import json
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",3008))
print("connect success....")
filepath = "1.png"
size =  os.stat(filepath).st_size
f= struct.pack("l",os.stat(filepath).st_size)
client.send(f)
img = open(filepath,"rb")
client.sendall(img.read())
img.close()
client.close()

××××××××××××方法二(推荐):

方法二:
	发送端(事先知道接收的缓冲区大小buf)
1、读取要发送的文件,获取总大小
2、每次发送buf大小的数据,是的接收端正好接这么多
3、一直发,直到把文件的数据发送完
	接收端
1、一直接收直到数据的不大于0

第二种方法最终代码:

#服务器
import socket
import struct
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",3008))
server.listen(3)
while True:
    print("start......")
    sock,adddr = server.accept()
    total_data = b''
    num = 0
    data = sock.recv(1024)
    total_data += data
    num =len(data)
    # 如果没有数据了,读出来的data长度为0,len(data)==0
    while len(data)>0:
        data = sock.recv(1024)
        num +=len(data)
        total_data += data       
    with open("11.png","wb") as f:
        f.write(total_data)
    sock.close()
sock.close()
#客户端
import socket 
import struct
import os
import json

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",3008))
print("connect success.....")
filepath = "1.png"
img = open(filepath,"rb")
# print(len(img.read()))

client.sendall(img.read())
img.close()
client.close()

使用python socket分发大文件

python socket编程(传输字符、文件、图片)

struct.pack()、struct.unpack()和struct.calcsize()

socket中AF_*** 和socket.SOCK_STREAM的资料来自《python核心编程》
套接字是计算机网络数据结构,它体现了上节中所描述的“通信端点”的概念。在任何
类型的通信开始之前,网络应用程序必须创建套接字。可以将它们比作电话插孔,没有它将
无法进行通信。
套接字的起源可以追溯到 20 世纪 70 年代,它是加利福尼亚大学的伯克利版本 UNIX(称
为 BSD UNIX)的一部分。因此,有时你可能会听过将套接字称为伯克利套接字或 BSD 套接
字。套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个
进程)与另一个运行的程序进行通信。这就是所谓的进程间通信(Inter Process Communication,
IPC)。有两种类型的套接字:基于文件的和面向网络的。
UNIX 套接字是我们所讲的套接字的第一个家族,并且拥有一个“家族名字” AF_UNIX
(又名 AF_LOCAL,在 POSIX1.g 标准中指定),它代表地址家族(address family): UNIX。
包括 Python 在内的大多数受欢迎的平台都使用术语地址家族及其缩写 AF;其他比较旧的系
统可能会将地址家族表示成域(domain)或协议家族(protocol family),并使用其缩写 PF 而
非 AF。类似地, AF_LOCAL(在 2000~2001 年标准化)将代替 AF_UNIX。然而,考虑到
后向兼容性,很多系统都同时使用二者,只是对同一个常数使用不同的别名。 Python 本身仍
然在使用 AF_UNIX。
因为两个进程运行在同一台计算机上,所以这些套接字都是基于文件的,这意味着文件
系统支持它们的底层基础结构。这是能够说得通的,因为文件系统是一个运行在同一主机上
的多个进程之间的共享常量。
第二种类型的套接字是基于网络的,它也有自己的家族名字 AF_INET,或者地址家族:
因特网。另一个地址家族 AF_INET6 用于第 6 版因特网协议(IPv6)寻址。此外,还有其他
的地址家族,这些要么是专业的、过时的、很少使用的,要么是仍未实现的。在所有的地址
家族之中,目前 AF_INET 是使用得最广泛的。
Python 2.5 中引入了对特殊类型的 Linux 套接字的支持。套接字的 AF_NETLINK 家族(无
连接[见 2.3.3 节])允许使用标准的 BSD 套接字接口进行用户级别和内核级别代码之间的 IPC。
之前那种解决方案比较麻烦,而这个解决方案可以看作一种比前一种更加优雅且风险更低的
解决方案,例如,添加新系统调用、 /proc 支持,或者对一个操作系统的“IOCTL”。
针对 Linux 的另一种特性(Python 2.6 中新增)就是支持透明的进程间通信(TIPC)协
议。 TIPC 允许计算机集群之中的机器相互通信,而无须使用基于 IP 的寻址方式。 Python 对
TIPC 的支持以 AF_TIPC 家族的方式呈现。
总的来说, Python 只支持 AF_UNIX、 AF_NETLINK、 AF_TIPC 和 AF_INET 家族。因为
本章重点讨论网络编程,所以在本章剩余的大部分内容中,我们将使用 AF_INET。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python socket传输大文件的方法 的相关文章

随机推荐

  • 图片加载框架-Picasso最详细的使用指南

    写在前面 Android 中有几个比较有名的图片加载框架 Universal ImageLoader Picasso Glide和Fresco 它们各有优点 以前一直用的是ImageLoader 做项目中的图片加载 由于作者宣布ImageL
  • 全国职业技能大赛云计算--高职组赛题卷⑤(容器云)

    全国职业技能大赛云计算 高职组赛题卷 容器云 第二场次题目 容器云平台部署与运维 任务2 基于容器的web应用系统部署任务 15分 任务3 基于容器的持续集成部署任务 15分 任务4 Kubernetes容器云平台部署与运维 15分 本任务
  • 目标检测算法部署网页web端2-点击按钮加载本地图像

    上一篇写了页面的html 目标检测算法部署网页web端1 这篇加个如何点击图像加载按钮 显示在页面上 效果如下 代码如下 b b
  • 【Three.js】第十二章 Materials 材质

    12 Materials 材质 介绍 材质用于为几何体的每个可见像素着色 决定每个像素颜色的算法属于着色器中编写的 编写着色器是 WebGL 和 Three js 最具挑战性的部分之一 但不要担心 Three js 有许多带有预制着色器的内
  • 005 python连接hive

    环境安装 hive hive 安装包配置 python配置hive环境pip install sasl pip install thrift pip install thrift sasl pip install PyHive 注 安装sa
  • CVE-2021-31956提权漏洞分析与利用

    声明 以下内容 来自先知社区的任意门作者原创 由于传播 利用此文所提供的信息而造成的任何直接或间接的后果和损失 均由使用者本人负责 长白山攻防实验室以及文章作者不承担任何责任 漏洞介绍 CVE 2021 31956是发生在NTFS sys中
  • 如何使用Git从网站上拉代码文件

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 Github项目 二 复制文件下载链接 三 将文件下载到我们自己的文件夹中 总结 前言 很多时候我们想从Github网站找到一个想要的项目文件 想要下载下
  • antdv + moment DatePicker日期组件默认显示当天、当周、当月

    一 当天 两种形式 1 非表单
  • 黑马程序员Javaweb学习笔记01

    该博客主要记录在学习黑马程序员Javaweb过程的一些笔记 方便复习以及加强记忆 系列文章 JavaWeb学习笔记01 BS架构 Maven Tomcat Servlet JavaWeb学习笔记02 request和response Jav
  • HY2120的保护板和充电方案整套电路图

    HY2102保护板电路和9V 20V输入的锂电池充电芯片PW4203电路 HY2102保护板电路和5VV输入的锂电池充电芯片PL7501C电路
  • 已解决Win11报错 OSError: [WinError 1455] 页面文件太小,无法完成操作。

    作者主页 爱笑的男孩 的博客 CSDN博客 深度学习 活动 python领域博主爱笑的男孩 擅长深度学习 活动 python 等方面的知识 爱笑的男孩 关注算法 python 计算机视觉 图像处理 深度学习 pytorch 神经网络 ope
  • GD32ADC+DMA定时电压采集(备份)

    初始化了一个串口 初始化了一个adc 一个dma 一个定时器 一个led 这一套搞懂算是基本入门了呀 include gd32f4xx h include systick h include
  • 2)Cadence design entry hdl Tutorial原理图入门

    从最基本的步骤 新建项目开始 1 1项目的组成 参考库是包含原理图符号 sym 的库 显示在原理图上的元件 代表实际的器件 包含封装型号 a Local libraries design libraries 本地库 设计库 项目自动生成的
  • 编程经验分享(寻找map中的max与min)——力扣·百战炼磨(一)

    2021 4 14 力扣第47场双周赛 虚拟竞赛 第三题 所有子字符串美丽值之和 力扣 1781 以下经验来自于对该题目的解决 一个字符串的 美丽值 定义为 出现频率最高字符与出现频率最低字符的出现次数之差 比方说 abaacc 的美丽值为
  • 编辑器mavon-editor离线使用

    cnd部分 可与运维人员商量一起配置 vue2的使用 1 1在public文件夹下面 放入编辑器的全部文件 1 2引入 1 2 1script下面引入 import Vue from vue import mavonEditor from
  • C# 基础知识 (五).变量类型和字符串处理

    这篇文章是阅读 C 入门经典 Beginning C 书籍里面的内容 作者Karli Watson 主要包括自己缺乏的一些C 基础知识和在线笔记使用 文章主要包括C 简单变量类型和复杂变量类型 命名规则 隐式转换和显示转换 变量字符串处理等
  • CNN卷积神经网络

    CNN卷积神经网络 前言 一 相关概念 卷积 彩色图像卷积 池化 padding Dropout正则化 局部归一化 二 经典网络 AlexNet VGGNet介绍 GoogLeNet ResNet介绍 resnet解决方案 结果 三 实操一
  • 【卷积神经网络】12、激活函数

    文章目录 一 Tanh 二 Sigmoid 三 ReLU 四 Leaky ReLU 五 ELU 六 SiLU 七 Mish 本文主要介绍卷积神经网络中常用的激活函数及其各自的优缺点 最简单的激活函数被称为线性激活 其中没有应用任何转换 一个
  • 数学建模——阅读论文的重要性

    1 我们来交流下怎么拿奖吧 数学建模竞赛虽然它的初衷是非常好的 需要体现一个人应用数学的能力以及创兴能力 但是实际上 经过我多年的比赛 发现其实绝大多数获奖 包括国家一等奖 也是可以通过一定的学习以及一定的技巧来获取的 对于数学建模新手来说
  • python socket传输大文件的方法

    方法一 发送端 1 计算发送文件大小 然后结合文件的其他信息 组成文件头先发送一次 2 发送文件数据时用sendall 一次发送所有数据 好像是重复调用了send 接收端 1 接收端根据接受文件的大小和recv size计算要接收数据的次数