python——网络编程之基于TCP协议的文件上传和下载

在这里我实现的是客户端上传文件,服务器接收文件,如果要实现客户端从服务器上下载文件的话,直接将代码反过来即可。废话不多说,下面直接上代码吧。

下面是服务器端的代码

import socket
import struct
import json

sk = socket.socket()
sk.bind(('127.0.0.1', 8888))  # 绑定ip地址和端口
sk.listen()   # 开启监听

buffer = 1024  # 缓冲区大小,这里好像因为windows的系统的原因,这个接收的缓冲区不能太大

conn, addr = sk.accept()  
# 先接收报头的长度
head_len = conn.recv(4)
head_len = struct.unpack('i', head_len)[0]  # 将报头长度解包出来
# 再接收报头
json_head = conn.recv(head_len).decode('utf-8')   # 拿到的是bytes类型的数据,要进行转码
head = json.loads(json_head)   # 拿到原本的报头
file_size = head['filesize']
with open(head['filename'], 'ab') as f:
    print(file_size)
    while file_size:
        if file_size >= buffer:  # 判断剩余文件的大小是否超过buffer
            content = conn.recv(buffer)
            f.write(content)
            file_size -= buffer
        else:
            content = conn.recv(file_size)
            f.write(content)
            file_size = 0
            break
conn.close()
sk.close()

下面是客户端的代码

import socket
import os
import json
import struct

sk = socket.socket()
sk.connect(('127.0.0.1', 8888))  # 与服务器建立连接

buffer = 1024
# 定制我们的报头,这里的报头不是唯一的,你可以根据你的想法去更改
head = {'filepath': r'你的文件路径',
        'filename': r'你要传的文件名',
        'filesize': None}  
file_path = os.path.join(head['filepath'], head['filename'])
# 计算文件的大小
filesize = os.path.getsize(os.path.join(head['filepath'], head['filename']))  
head['filesize'] = filesize
json_head = json.dumps(head)  # 利用json将字典转成字符串
bytes_head = json_head.encode('utf-8')    # 字符串转bytes
# 计算head长度
head_len = len(bytes_head)  # 报头的长度
# 利用struct将int类型的数据打包成4个字节的byte,所以服务器端接受这个长度的时候可以固定缓冲区大小为4
pack_len = struct.pack('i', head_len) 
# 先将报头长度发出去
sk.send(pack_len)
# 再发送bytes类型的报头
sk.send(bytes_head)
with open(file_path, 'rb') as f:
    while filesize:
        print(filesize)
        if filesize >= buffer:
            content = f.read(buffer)  # 每次读取buffer字节大小内容
            filesize -= buffer
            sk.send(content)  # 发送读取的内容
        else:
            content = f.read(filesize)
            sk.send(content)
            filesize = 0
            break
sk.close()

在这个上传、下载文件的实验中,发现了一个现象,就是buffer基本不能超过1024字节大小,,如果超过1024的大小就会报错,这可能与windows操作系统有关,可能是由于读写不同步造成的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章