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/ ...
随机推荐
- Mysql 查询最近一年的数量sql
按月查询分月数量 , 某个月份没有的显示为0 SELECT@s := @s + 1 AS `index`,DATE_FORMAT( DATE_SUB( CURDATE(), INTERVAL @s M ...
- Vant+小程序+购物车实例
图片实例,看是否是您所需要的喔.... 扫码小程序可看实例操作,有啥问题也可扫码加群,很希望可以帮助到你喔! HTML部分: <view class="cart&q ...
- JavaScript数据类型以及转换
一.数据类型 分类 基本(值)类型: String Number Boolean undefined unll 对象(引用)类型: Object:任意对象 Array:一种特别的对象 Function ...
- nuxt,js中关于服务端不能使用localStorage和cookie的解决方案
参考链接:https://www.npmjs.com/package/cookie-universal-nuxt 1.安装下载 npm i --save cookie-universal-nuxt 2 ...
- char和int的类型转换
char类型是16位的,底层采用unicode编码保存.char类型是可以直接赋值给int类型的,因为是16位到32位低到高.举个例子比如int i='1';打印i的值是49.char类型跟int类型 ...
- 关于IllegalMonitorStateException异常的解释之一
注意 在同步控制方法或同步控制块里调用wait(),notify()和notifyAll().如果在非同步控制方法里调用这些方法,程序能通过编译,但运行的时候,将得到IllegalMonitorSta ...
- centos7 安装 elasticsearch 7.15
下载 elasticsearch wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.2-linu ...
- K8S的基础概念
一.Kubernetes介绍 1.什么是Kubernetes? Kubernetes(通常称为K8s,K8s是将8个字母"ubernete"替换为"8"的缩写) ...
- cpu的调度
什么是cpu的调度 所谓 CPU 调度,就是确定把哪个处于淮备就绪状态的进程移入运行状态.也就是说,CPU调度算法将决定把 CPU 给予哪个进程,以便它能够运行. 两种调度方式 CPU 调度可以是在一 ...
- (五).JavaScript的函数
1. 函数 1.1 函数基础简介 函数介绍 函数:具有特定功能的代码块 本质:一种对象数据类型 功能:1. 代码复用 2. 项目模块化 函数组成(两者必须同时存在): 1. 函数定义 2. 函数调用 ...