Python Socket实现文件上传(TCP协议)

在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

 

转载于:https://www.cnblogs.com/yueyun00/p/10027033.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值