在TCP协议下通过socket模块实现文件上传

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# desc: tcp_server_file_upload import socket
import struct
import json
import time IP_PORT = ('127.0.0.1', 8080)
BUFFERSIZE = 1024 tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #获取socket对象,并设置通过TCP协议通信
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)#设置连接重用
tcp_server_socket.bind(IP_PORT) #绑定IP地址和端口
tcp_server_socket.listen() #监听,可指定数量 conn, addr = tcp_server_socket.accept() #建立连接
print('client ip addr:', addr)
head_struct = conn.recv(4) #接收定制报头的长度
head_json_len = struct.unpack('i', head_struct)[0] #解包,获取定制报头的长度
head_json = conn.recv(head_json_len).decode('utf-8') #根据上一步解包获得的报头长度,接收报头
head = json.loads(head_json) #将json字符串类型的报头转化为python对象
file_size = head['file_size']#获取待接收文件的大小
file_name = head['file_name']#获取接收文件的名字
print(time.strftime('%Y-%m-%d %H:%M:%S'),' 开始接收文件...') #打印开始接收文件的时间
with open(file_name, 'wb') as f: #以二进制写方式打开文件
'''
循环写入接收的文件内容
'''
while True:
if file_size >= BUFFERSIZE: #如果接收的文件内容大于设置的BUFFERSIZE,就只接收BUFFERSIZE大小的内容
content = conn.recv(BUFFERSIZE) #接收客服端发送的BUFFERSIZE大小的内容
f.write(content) #在服务端写入BUFFERSIZE大小的内容
file_size -= BUFFERSIZE #将待写入的文件大小减去已接收的BUFFERSIZE大小
'''
主要是用于服务端和客户端在同一PC上,且写入比读取快,从而导致服务端先行关闭,
造成客户端连接中断,文件传送不完整
'''
time.sleep(0.00001)
else:
content = conn.recv(file_size) #接收文件剩余部分
f.write(content)
break
print(time.strftime('%Y-%m-%d %H:%M:%S'),' 成功接收文件...') #打印文件接收完成时间 conn.close() #关闭连接
tcp_server_socket.close() #关闭服务端socket

tcp_server_file_upload

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @desc: tcp_client_file_upload import socket
import struct
import json
import os
import time IP_PORT = ('127.0.0.1', 8080)
BUFFERSIZE = 1024 tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #获取socket对象
tcp_client_socket.connect(IP_PORT) #连接服务端 '''
定制化报头
'''
head = {'file_path':r'文件路径',
'file_name':r'文件名',
'file_size':0
} file_path = os.path.join(head['file_path'], head['file_name']) #获取要上传文件的完整路径
file_size = os.path.getsize(file_path) #获取文件大小
head['file_size'] = file_size #将获取到的真实文件大小设置到报头 head_json = json.dumps(head) #将报头python对象转化为json字符串
head_bytes = bytes(head_json, encoding='utf-8') #将报头json字符串转化为bytes字节码
head_struct = struct.pack('i', len(head_bytes)) #将报头bytes字节码以'integer'类型打包为4个字节
tcp_client_socket.send(head_struct) #发送打包为4个字节的报头
tcp_client_socket.send(head_bytes) #发送定制化报头
print(time.strftime('%Y-%m-%d %H:%M:%S'),' 开始发送文件...') #打印开始发送文件的时间
with open(file_path, 'rb') as f: #以二进制读的方式打开文件
'''
循环读取文件内容并发送给服务端
'''
while True:
if file_size >= BUFFERSIZE: #如果发送文件的大小大于BUFFERSIZE,只读取BUFFERSIZE大小的内容
content = f.read(BUFFERSIZE) #读取BUFFERSIZE大小的内容
tcp_client_socket.sendall(content) #发送读取的文件内容
file_size -= BUFFERSIZE #文件大小减去已发送文件的大小
else:
content = f.read(file_size) #读取剩余文件内容
tcp_client_socket.sendall(content) #发送文件读取的文件内容
break #终止循环 print(time.strftime('%Y-%m-%d %H:%M:%S'),' 文件发送成功...') #大于文件发送完成的时间
tcp_client_socket.close() #关闭socket

tcp_client_file_upload

最新文章

  1. Android源码——Logger日志系统
  2. 用Struts2拦截器实现文件下载前的验证
  3. 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.0,完善基础功能(源码)
  4. 关闭和启动adb服务命令
  5. 剑指Offer:面试题26——复制复杂的链表(java实现)
  6. rpm 命令参数使用详解
  7. appledoc导出iOS代码文档的使用和问题详解(干货篇)
  8. 论文笔记 Spatial contrasting for deep unsupervised learning
  9. Rigidbody组件及相关API
  10. docker_macvlan
  11. 安装包安装npm
  12. Spring Security 用户认证原理分析
  13. PHP中冒号、endif、endwhile、endfor使用介绍
  14. mysql备份与恢复数据
  15. 关于CSS的知识
  16. J2EE的13个规范总结
  17. php -- 魔术方法 之 获取属性:__get()
  18. 解决delphi10.2.3 android tools闪退
  19. LINQ 方法
  20. Word 2013发布博客测试

热门文章

  1. Unity3D Shader 高斯模糊
  2. Matlab 瑞利信道仿真
  3. E - 487--3279
  4. windows 上的 neovim 配置
  5. chfn是用来改变你的finger讯息
  6. 操作系统中的IPC机制(inter-process Communication)
  7. db2 reorg table failed处理
  8. 配置hadoop集群,完全分布式模式
  9. Python使用xml.dom解析xml
  10. [skill] 异或