python发送文件

一.简介

有需要发送文件的需求
python发送文件

思路:

  1. 先将报头转换成字符串(json.dumps), 再将字符串的长度打包
  2. 发送报头长度,发送报头内容,最后放真是内容
  3. 报头内容包括文件名,文件信息,报头
  4. 接收时:先接收4个字节的报头长度,
  5. 将报头长度解压,得到头部信息的大小,在接收头部信息, 反序列化(json.loads)
  6. 最后接收真实文件

二.客户端发到服务端

master.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from socket import *
import struct
import json
import os
import sys
import time


tcp_server = socket(AF_INET, SOCK_STREAM)
ip_port = (('172.16.5.4', 7777))
buffsize = 1024

#   端口的重复利用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
tcp_server.bind(ip_port)
tcp_server.listen(200)

while True:
    '''链接循环'''
    print("等待客户端连接...")
    conn, addr = tcp_server.accept()

    print('链接人的信息:', addr)
    head_struct = conn.recv(4)  # 接收报头的长度,
    if head_struct:
        print('已连客户端,等待接收数据')
    head_len = struct.unpack('i', head_struct)[0]  # 解析出报头的字符串大小
    data = conn.recv(head_len)  # 接收长度为head_len的报头内容的信息 (包含文件大小,文件名的内容)

    head_dir = json.loads(data.decode('utf-8'))
    filesize_b = head_dir['filesize_bytes']
    filename = head_dir['filename']

    #   接受真的文件内容
    recv_len = 0
    recv_mesg = b''
    old = time.time()
    f = open(filename, 'wb')
    while recv_len < filesize_b:
        percent = recv_len / filesize_b

        if filesize_b - recv_len > buffsize:

            recv_mesg = conn.recv(buffsize)
            f.write(recv_mesg)
            recv_len += len(recv_mesg)
        else:
            recv_mesg = conn.recv(filesize_b - recv_len)
            recv_len += len(recv_mesg)
            f.write(recv_mesg)

    print(recv_len, filesize_b)
    now = time.time()
    stamp = int(now - old)
    print('总共用时%ds' % stamp)
    f.close()

slave.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from socket import *
import struct
import json
import os


tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('172.16.5.4', 7777))
buffsize = 1024
tcp_client.connect_ex(ip_port)

filename = 'gitlab-Statistics.py'
filesize_bytes = os.path.getsize(filename) # 得到文件的大小,字节
dirc = {
    'filename': filename,
    'filesize_bytes': filesize_bytes,
}
head_info = json.dumps(dirc)  # 将字典转换成字符串
head_info_len = struct.pack('i', len(head_info)) #  将字符串的长度打包
tcp_client.send(head_info_len)  # 发送head_info的长度
tcp_client.send(head_info.encode('utf-8'))

#   发送真是信息
with open(filename, 'rb') as f:
    data = f.read()
    tcp_client.sendall(data)

print('发送成功')

三.服务端发到客户端

master.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-5-21 下午1:59
# @Author  : LK
# @File    : 文件传输-服务端.py
# @Software: PyCharm

from socket import *
import struct
import json
import os

tcp_server = socket(AF_INET, SOCK_STREAM)
ip_port = (('172.16.1.46', 7777))
buffsize = 1024

#   端口的重复利用
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
tcp_server.bind(ip_port)
tcp_server.listen(5)
print('还没有人链接')
while True:
    '''链接循环'''
    conn, addr = tcp_server.accept()

    print('链接人的信息:', addr)
    while True:
        if not conn:
            print('客户端链接中断')
            break
        '''通信循环'''
        #filemesg = input('请输入要传送的文件名加后缀>>>').strip()
        filemesg = 'gitlab-Statistics.py'
        filesize_bytes = os.path.getsize(filemesg) # 得到文件的大小,字节
        filename = 'new' + filemesg
        dirc = {
            'filename': filename,
            'filesize_bytes': filesize_bytes,
        }
        head_info = json.dumps(dirc)  # 将字典转换成字符串
        head_info_len = struct.pack('i', len(head_info)) #  将字符串的长度打包
        #   先将报头转换成字符串(json.dumps), 再将字符串的长度打包
        #   发送报头长度,发送报头内容,最后放真是内容
        #   报头内容包括文件名,文件信息,报头
        #   接收时:先接收4个字节的报头长度,
        #   将报头长度解压,得到头部信息的大小,在接收头部信息, 反序列化(json.loads)
        #   最后接收真实文件
        conn.send(head_info_len)  # 发送head_info的长度
        conn.send(head_info.encode('utf-8'))

        #   发送真是信息
        with open(filemesg, 'rb') as f:
            data = f.read()
            conn.sendall(data)

        print('发送成功')
        break

slave.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-5-21 下午1:59
# @Author  : LK
# @File    : 文件传输_客户端.py
# @Software: PyCharm

from socket import *
import struct
import json
import os
import sys
import time
#from 进度条 import process_bar

tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('172.16.1.46', 7777))
buffsize = 1024
tcp_client.connect_ex(ip_port)
print('等待链接服务端')
while True:
    head_struct = tcp_client.recv(4)  # 接收报头的长度,
    if head_struct:
        print('已连接服务端,等待接收数据')
    head_len = struct.unpack('i', head_struct)[0]  # 解析出报头的字符串大小
    data = tcp_client.recv(head_len)  # 接收长度为head_len的报头内容的信息 (包含文件大小,文件名的内容)

    head_dir = json.loads(data.decode('utf-8'))
    filesize_b = head_dir['filesize_bytes']
    filename = head_dir['filename']

    #   接受真的文件内容
    recv_len = 0
    recv_mesg = b''
    old = time.time()
    f = open(filename, 'wb')
    while recv_len < filesize_b:
        percent = recv_len / filesize_b

#        process_bar(percent)
        if filesize_b - recv_len > buffsize:

            recv_mesg = tcp_client.recv(buffsize)
            f.write(recv_mesg)
            recv_len += len(recv_mesg)
        else:
            recv_mesg = tcp_client.recv(filesize_b - recv_len)
            recv_len += len(recv_mesg)
            f.write(recv_mesg)

    print(recv_len, filesize_b)
    now = time.time()
    stamp = int(now - old)
    print('总共用时%ds' % stamp)
    f.close()
上一篇:psutil模块详解


下一篇:厦门大学计算机网络第三次实验