ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python发送文件

2021-12-15 09:33:48  阅读:145  来源: 互联网

标签:文件 head python len 发送 tcp import 报头 recv


一.简介

有需要发送文件的需求
file

思路:

  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()

标签:文件,head,python,len,发送,tcp,import,报头,recv
来源: https://www.cnblogs.com/rxysg/p/15691113.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有