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/ ...
随机推荐
- python 项目启动
批量执行requirements.txt文件: pip install -r requirements.txt 清华镜像源安装: pip install -i https://pypi.tuna.ts ...
- Jmeter二、开始使用
一.最简单的性能测试脚本 testplan→ thread group→HTTP request→view results tree.jmx后缀文件,xml文件校验 二.使用过程中其他需要注意的 1. ...
- homework1(1)
来自桂林理工大学物联网工程2019届的April 没参与过什么比赛项目但是课程学习能力还行,主要是快速学习之后很快就会忘记,接下来应该好好的总结并熟练记住运用知识完成对生活等各种的实践. 对课程的希望 ...
- SQL Server 错误:特殊符号“•”导致的sql查询问题
问题描述: 对于一些标题或字符串,例如: 如果导入数据库,就会发现会自动变成?号了: 在进行SQL查询的时候,会出现一个同一条sql语句在mysql直接执行sql可以查询到,但是mssql进行查询的时 ...
- jmeter&badboy安装
一.jmeter下载地址: 1. http://jmeter.apache.org/download_jmeter.cgi \ https://www.apache.org/dist/jmete ...
- renren-fast-vue人人开源前端项目搭建保姆级教程
1.从gitee上clone项目 git clone https://gitee.com/renrenio/renren-fast-vue.git 2.准备好python环境 需要有Python2以上 ...
- Java 题目集 编程
7-1 多数组排序 (20 分) 3个整数数组进行整体排序,根据输入的三个数组的元素,输出排序后的结果(从大到小) 输入格式: 第1个数组的长度 第1个数组的各个元素 第2个数组的长度 第2个数组 ...
- CF1732A Bestie
思路 观察数据\(n \le 20\) 直接暴力. 我们直接算所有数的\(GCD\),然后枚举\(1\)~\(n\)的每一个数要不要选,然后选的话,就把原来的\(GCD\)和当前枚举的数\(GCD\) ...
- 看图就会-react条件渲染的5种方式
- Python中列表、元组、字典的区别
列表: 列表是一种数据结构,每一个元素对应一个值.例如:list=['a','b','c'] 访问列表数据通过下标的方式来进行数据访问,list[下标] list.append(i) 添加数据 de ...