定制报文——文件的上传下载

报文的概念:

  我们在网络上传输的所有数据,都叫数据包,数据包里的所有数据都叫报文。

  报文里含有你的数据,IP地址,MAC地址,端口号等

  所有的报文都有报头,根据报头可以知道接收多少个字节

自定义报文

  例如:传输文件,需要传输的内容如下

  文件名,文件大小,文件类型,存储路径

  head = {'filename':'test','filesize':10000,'filetype':'txt','filepath':r'\usr\bin'}

  顺序:

    报头的长度————————————先接收4给字节

    send(head) #报头—————————根据这4个字节获取报头

    send(file)    # 报文—————————从报头中获取filesize,然后根据filesize接收文件

上传端

# 发送端
import socket
import os
import json
import struct
buffer = 1024
sk = socket.socket()
sk.connect(('127.0.0.1',8090))

# 发送文件
head = {'filepath':r'C:\Users\Mr.Feng\Pictures\Saved Pictures',
        'filename':r'99eae72194524579f72b253436689019.jpg',
        'filesize':None
        }
filepath = os.path.join(head['filepath'],head['filename'])
filesize = os.path.getsize(filepath)
head['filesize'] = filesize
json_head = json.dumps(head)    # 字典转成字符串
bytes_head = json_head.encode('utf-8')
# 计算head长度
head_len = len(bytes_head)
pack_head = struct.pack('i',head_len)
print(head_len,pack_head)
sk.send(pack_head)  # 先发报头长度
sk.send(bytes_head) # 再发送bytes类型报头
with open(filepath,'rb') as f:
    while filesize:
        print(filesize)
        if filesize>=buffer:
            content = f.read(buffer)
            sk.send(content)
            filesize -= buffer
        else:
            content = f.read(filesize)
            sk.send(content)
            break
sk.close()
发送端

下载端

# 实现一个大文件的上传或者下载
# 配置文件:IP地址,端口号
import json
import socket
import struct
buffer = 1024
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen(0)

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')
head = json.loads(json_head)
filesize = head['filesize']
with open(head['filename'],'wb') as f:
    while filesize:
        print(filesize)
        if filesize>=buffer:
            content = conn.recv(buffer)
            f.write(content)
            filesize -= buffer
        else:
            content = conn.recv(filesize)
            f.write(content)
            break
conn.close()
sk.close()
接收端

猜你喜欢

转载自www.cnblogs.com/Mr-Feng/p/10886595.html