socket与struct实战应用(传输文件)
服务端
需求:制作一个可以接收文件的服务,操作客户端往服务端传输文件
服务端代码
import struct
import socket
import json
import os
# 1. 先起动服务端服务
server = socket.socket()
server.bind(('localhost', 18000))
server.listen(5)
by_client, addr = server.accept()
# 2. 接收客户端发送来的字典报头信息
by_client_stru_size = by_client.recv(4)
# 3. 接收后进行解压,获取到真实的字典大小
by_client_dict_size = struct.unpack('i', by_client_stru_size)[0]
# 4. 按真实的字典大小进行接收客户端的字典信息,并使用json反序列化,得到字典信息
# 4. 这时候的文件大小为by_client_dict.get('file_size')
by_client_dict = json.loads(by_client.recv(by_client_dict_size))
file_size = by_client_dict.get('file_size')
# 5. 打开一个文件,并将接收到的二进制信息写入到文件中
with open(by_client_dict.get('file_name'), 'wb') as f:
while True:
'''
思路:
1. 每次接收到的文件大小不宜过大,否则会过度消耗服务器资源,最大不要设置超过1024*8大小
2. 因为是三次握手为流式接收文件,所以多次接收没有问题。
'''
# 1. 先获取当前服务器本身文件大小(首次肯定是0)
server_file_size = os.path.getsize(by_client_dict.get('file_name'))
# 2. file_size为最终文件大小,这个是从字典中获取到的,客户端在发送的时候就指定好了
# 2. 真实文件大小减去服务器当时文件的大小,可得到还未接收到的文件大小
receive_server_file_size = file_size - server_file_size
# 3. 如果还未接收到的文件大于1024字节,则接收的时候就使用1024大小进行接收
# 例如:本次接收的文件为57123945字节大小,那么前几次接收后,未接收到的文件大小依次为:
# 57,122,921/57,121,897/57,120,873....接收55785次后还剩105字节大小
if receive_server_file_size > 1024:
f.write(by_client.recv(1024))
# 4. 如果接收到最后,未接收到的文件小于或者等于1024,则使用还未接收到的文件大小进行接收
# 接第三步的例子,现在还剩105字节大小
elif receive_server_file_size <= 1024: # 此时105 < 1024,就走这个if分支
f.write(by_client.recv(receive_server_file_size)) # 这时候就按105字节进行接收
print('文件接收成功') # 走到这个if分支证明文件已传输至最后,传输完这次后打印接收成功
break # 最后跳出循环,不再接收文件
客户端代码:
import struct, socket, os, json
client = socket.socket()
# 1. 客户端连接服务器
client.connect(('localhost', 18000))
# 2. 获取真实文件大小
file_size = os.path.getsize(r'D:\迅雷下载\Edius_Pro_8.10.188.rar')
# 3. 定义字典,将真实文件大小写入进去
send_dict = {
'file_name': 'edius_test.rar',
'file_size': file_size,
'file_info': '我是一个视频剪辑软件,很多人都在用!'
}
# 4. 序列化字典
file_json = json.dumps(send_dict).encode('utf8')
# 5. 获取字典的真实长度,将真实长度制作成头部信息并发送给服务器端,这样,服务端就可以根据字典的真实长度来接收字典了。
file_head = struct.pack('i', len(file_json))
# 6. 将制作好的报头发送给服务端,服务端进行解压后可得出序列化后的字典长度,再根据字典长度进行接收
client.send(file_head)
# 7. 发送字典,字典中有记录真实的文件大小信息,也就是file_size,服务端解压后,获取到真实的file_size后,再根据file_size大小制定接收的策略
client.send(file_json)
# 8. 最后一步发送真实的文件。
with open(r'D:\迅雷下载\Edius_Pro_8.10.188.rar', 'rb') as f:
# 分步发送的原因是,可以节省内存开支,如果是非常大的文件,会占用大量内存,有可能会撑暴
for line in f:
client.send(line)
print('文件已发送完成')
socket与struct实战应用(传输文件)的更多相关文章
- Python Socket传输文件
发送端可以不停的发送新文件,接收端可以不停的接收新文件. 例如:发送端输入:e:\visio.rar,接收端会默认保存为 e:\new_visio.rar,支持多并发,具体实现如下: 接收端: 方法一 ...
- python socket 传输文件
推荐资料 https://www.cnblogs.com/xiaokang01/p/9865724.html socket传输文件 思路: # 先将报头转换成字符串(json.dumps), 再将字符 ...
- Java使用Socket传输文件遇到的问题(转)
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
- Java使用Socket传输文件遇到的问题
1.写了一个socket传输文件的程序,发现传输过去文件有问题.找了一下午终于似乎找到了原因,记录下来警示一下: 接受文件的一端,向本地写文件之前使用Thread.sleep(time)休息一下就解决 ...
- java socket通信-传输文件图片--传输图片
ClientTcpSend.java client发送类 package com.yjf.test; import java.io.DataOutputStream; import java.io ...
- 采用socket传输文件
采用socket传输文件 客户端输入文件的地址,服务端判断文件存在,就将文件传输到客户端 package com.fly.socket; import java.io.BufferedInputStr ...
- Linux实战(2):Linux传输文件
此次使用的是scp命令,只是针对文件或者文件的传输,并没有什么高端的使用,主要是怕自己忘记了记一下. 传输文件,命令说明:scp+文件路径针确到文件名+账号+上传到另一台的路径并另存为文件名 scp ...
- 黏包-黏包的成因、解决方式及struct模块初识、文件的上传和下载
黏包: 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包. 只有TCP协议中才会产生黏包,UDP协议中不会有黏包(udp协议中数 ...
- python传输文件
传输文件简单版 server端: import socket import struct import json import os share_dir = r'C:\py3Project\路飞\第三 ...
- socket发送文字、图片、文件---基于python实现
socket官方文档:https://docs.python.org/2/library/socket.html socket中文详细介绍:http://blog.csdn.net/rebelqsp/ ...
随机推荐
- 反序列化 sqlserver 中的 sysdiagrams,找到其中包含的表的信息
转载于:Script SQL Server 2005 diagrams to a file - CodeProject /** <summary> Based on ufn_Varbina ...
- ArrayList 的toArray的转换数组方法的注意事项
ArrayList 的toArray的转换数组方法的注意事项 toArray()一共有两个方法 toArray(T[] a) 和toArray() 源码是 进行使用toArray()方法时候,使用 ( ...
- opened by another process write access was denied sourceinsight
Ubuntu 16.04 安装Samba 和 windows 安装Source Insight weixin_43764544 2021-01-07 15:23:03 23 收藏 文章标签: linu ...
- 几行python代码完美操控手机
最近一直成谜于python代码带来的便利,今天打算学习下用python代码来控制操作手机,首先需要利用adb,通过安卓调试桥来达到目的,其实也可以用appium来实现,不过appium多数用在自动化测 ...
- python中的异常类
- Vue学习day1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- 任意的形如 z = F(x,y)的曲面生成与显示---基于OpenGL Core Profile
运行结果: (圆锥面) (抛物面) (马鞍面) 其中的做法是:从顶部看上去就是一个平面网格.每个点的 z.x的位置都是程序细分出来的(指定起始.结束.步长).比较固定.但高度 y 的计算使用 用户 ...
- How to Apply WebLogic Server (WLS) Patches Using Smart Update
本文目的: 描述weblogic10.3.6及之前的版本,如何通过Smart Update打补丁 先决条件: You should download and apply the enhanced Sm ...
- (Linux服务器)git添加SSH公钥后本地验证失败
环境:腾讯云Ubuntu x86_64 问题说明: 在配置了公钥后,一直提示我git@github.com: Permission denied (publickey). 解决办法: 先查看root/ ...
- 联想拯救者R9000P风扇拉满加强散热的方法
管软可以开野兽模式,但是风扇还不是最猛的.锻炼的时候为了保护硬件,牺牲风扇和噪音吧,方法如下:下载 RWEverything运行RW.exe点击笔记本图标+EC文字的图案 修改:B0+0D对应的数据, ...