socket传送文件
文件 socket 传送
2023-09-14 09:08:29 时间
一、文件传送步骤
我们要利用socket来实现下载一个文件,该如何操作呢?
服务端:
- 读取文件名
- 判断文件是否存在
- 检测文件大小(用于和客户端对比判断文件是否传送完毕)
- 发送文件大小给客户端
- 等待客户端确认(防止粘包)
- 打开文件
- 边读边发送数据
- md5验证
客户端:
- 发送命令
- 接收文件大小
- 返回确认
- 获取文件名
- 对比文件大小
- 写入文件
二、功能实现(ftp下载功能)
服务端:
# -*- coding: UTF-8 -*- import os import socket # TCP/IP协议, tcp ,如果不填写就是默认这个 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 9999)) server.listen() while True: # 可以接受多个客户端 conn, addr = server.accept() print('new conn', addr) while True: cmd_res = conn.recv(1024) if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉 print('client has lost...') break else: # 获取命令和文件名 cmd, filename = cmd_res.decode().split() print(cmd, filename) if os.path.isfile(filename): # 判断文件是否存在 # 文件大小 file_size = os.stat(filename).st_size # 发送文件大小 conn.send(str(file_size).encode(encoding='utf-8')) # 等待客户端确认 conn.recv(1024) # 打开文件 f = open(filename, 'rb') for line in f: conn.send(line) print('sending') f.close()
客户端:
# -*- coding: UTF-8 -*- import socket client = socket.socket() client.connect(('localhost', 9999)) while True: cmd = input('>>:').strip() # 判断是否发送空数据,如果是就重新发送 if len(cmd) == 0: continue else: client.send(cmd.encode('utf-8')) # 获取服务端发送的文件大小 size = client.recv(1024) total_file_size = int(size.decode()) # 返回确认 client.send(b'file size received') filename = cmd.split()[1] print(filename) received_size = 0 # 写入文件 f = open(filename + '.new', 'w', encoding='utf-8') while received_size < total_file_size: r_data = client.recv(1024) received_size += len(r_data) f.write(r_data.decode() + '\n') else: print('file sizes', total_file_size, received_size) print('receive finished') f.close()
有些问题 替换一些内容
f = open(filename + '.new', 'wb')
f.write(r_data)
这个程序有缺陷,首先目前只能读取本文件夹下的文件,新生成的文件没有中文乱码问题,ok...
三、md5验证文件
加个md5来验证文件是否一致
服务端:
# -*- coding: UTF-8 -*- import os import socket import hashlib # TCP/IP协议, tcp ,如果不填写就是默认这个 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('localhost', 9999)) server.listen() while True: # 可以接受多个客户端 conn, addr = server.accept() print('new conn', addr) while True: cmd_res = conn.recv(1024) if not cmd_res: # 防止当接受的客户端数据为空时,程序卡掉 print('client has lost...') break else: # md5 m = hashlib.md5() # 获取命令和文件名 cmd, filename = cmd_res.decode().split() print(cmd, filename) if os.path.isfile(filename): # 判断文件是否存在 # 文件大小 file_size = os.stat(filename).st_size print(file_size) # 发送文件大小 conn.send(str(file_size).encode(encoding='utf-8')) # 等待客户端确认 conn.recv(1024) # 打开文件 f = open(filename, 'rb') for line in f: m.update(line) # m.update('abc') m.update('123') # 其实和m.update('abc123') 结果一下 conn.send(line) f.close() print('send done') # 发送md5信息 conn.send(m.hexdigest().encode('utf-8'))
客户端:
# -*- coding: UTF-8 -*- import socket import hashlib client = socket.socket() client.connect(('localhost', 9999)) while True: cmd = input('>>:').strip() # 判断是否发送空数据,如果是就重新发送 if len(cmd) == 0: continue else: client.send(cmd.encode('utf-8')) # 获取服务端发送的文件大小 f_size = client.recv(1024) total_file_size = int(f_size.decode()) # 返回确认 client.send(b'file size received') filename = cmd.split()[1] print(filename) received_size = 0 # md5 m = hashlib.md5() # 写入文件 f = open(filename + '.new', 'wb') # 新生成的文件也正常显示 while received_size < total_file_size: if total_file_size - received_size > 1024: # 以此来控制只收文件的内容,不会粘包md5的内容 size = 1024 else: size = total_file_size - received_size r_data = client.recv(size) received_size += len(r_data) m.update(r_data) f.write(r_data) # print(r_data.decode()) # print('file sizes', total_file_size, received_size) else: print('file sizes', total_file_size, received_size) server_md5 = client.recv(1024).decode() client_md5 = m.hexdigest() print(server_md5) print(client_md5) print('receive finished') f.close()
结果:
结果看上去没有问题了,新文件也能生成,并且有内容
相关文章
- ASP.NET Core 6框架揭秘实例演示[20]:“数据保护”框架基于文件的密钥存储
- Atitit.远程文件技术 webdav ftp scp ssh-sftp http nfs smb 的区别与总结
- linux 错误码 65280,Android:无法在同一部手机上执行通过Linux部署编译的文件
- SpringBoot整合阿里云OSS文件上传、下载、查看、删除
- 生成和解析txt文件
- 安装gcc-arm-none-eabi-10-2020-q4-major-win32工具(NRF52编译ECC加密文件用)
- Python编程:yaml文件读写
- 【Android 内存优化】图片文件压缩 ( Android 原生 API 提供的图片压缩功能能 | 图片质量压缩 | 图片尺寸压缩 )
- Qt文件选择复制另存为
- 【Linux&Unix--文件描述叙事的性格和权柄】
- Linux在什么样的从脚本文件数据库sh格式改变sql格式
- MongoDB一个基于分布式文件存储的数据库(介于关系数据库和非关系数据库之间的数据库)
- 用UltraEdit比較两个文件
- LabVIEW写入可快速加载的TDMS文件
- 第二人生的源码分析(十六)保存人物角色的XML文件
- 1.1 文件上传之绕过验证