python-文件上传下载

一、数据粘包

【1】客户端两次发送请求,但是可能被服务端的同个recv收到,不能区分,会造成数据粘包(实际上需要服务端将两次请求区分接受)

二、服务器

# -*- coding:utf-8 -*-
# __author__:pansy
# 2022/5/14
import socket

# 创建socket对象
sk = socket.socket()
# 给服务器绑定ip和端口
sk.bind(('127.0.0.1',8889))
# 创建监听,监听客户端是否有发请求过来
sk.listen()

def get_file(sk_obj):
    '''
    接收文件
    :param sk_obj: 文件对象
    :return:
    '''
    # 从服务端会发送1个请求,用来传输文件大小,文件大小是整形,需要将string类型强转成int类型
    file_size = int(sk_obj.recv(1024).decode('utf8'))
    # 为了避免粘包,当执行完接收file_size语句后,需要告知post_file,文件大小已经接收成功
    sk_obj.sendall(b'ok')

    # 从服务端会发送1个请求,用来传输文件名称
    file_name = sk_obj.recv(1024).decode('utf8')
    sk_obj.sendall(b'ok')

    # 接收文件内容
    with open('./%s' %file_name,'wb') as f:
        while file_size > 0:
            f.write(sk_obj.recv(1024))
            file_size -= 1024


# 阻塞状态,若接收到数据,则阻塞解除
# accept返回一个套接字和客户端的ip端口
conn ,addr = sk.accept()

# 调用接收文件方法,conn是专门用来处理客户端业务的套接字
get_file(conn)

conn.close()
sk.close()

三、客户端

# -*- coding:utf-8 -*-
# __author__:pansy
# 2022/5/14
import os
import socket

# 创建socket对象
sk = socket.socket()
# 连接服务器,连接的是服务器绑定的ip和端口
sk.connect(('127.0.0.1',8889))

def post_file(sk_obj,file_path):
    '''
    发送文件,需要和接收文件一一对应
    :param sk_obj:文件对象
    :param file_path:文件路径
    :return:
    '''

    # 发送文件大小,用os.stat方法可以获取文件属性
    file_size = os.stat(file_path).st_size
    # 获取到的file_size是整形,不能直接编码,所以需要先强转成字符串
    sk_obj.sendall(str(file_size).encode('utf8'))
    # 为了避免粘包,需要用recv接收下参数,直到接收到ok后,才会继续下面的代码
    sk_obj.recv(1024)

    # 发送文件名称,用os.path.split方法,可以将文件路径切割成路径和文件名,返回这两个字段
    file_name = os.path.split(file_path)[1]
    sk_obj.sendall(file_name.encode('utf8'))
    sk_obj.recv(1024)

    # 发送文件内容,循环发送,1次发送1024个字节
    # 1、先读取文件,用rb二进制读取
    with open(file_path,'rb') as f:
        # 每发送1次,file_size会减少1024,不满足1024的,全部发送
        while file_size > 0:
            sk_obj.sendall(f.read(1024))
            file_size -= 1024

# 调用发送文件方法
path = '/Users/panshaoying/Desktop/database/data/img1.png'
post_file(sk,path)

sk.close()
posted on 2022-05-14 13:24  墙角一枝花  阅读(276)  评论(0编辑  收藏  举报