python 3.7 利用socket文件传输

参考:https://www.cnblogs.com/VseYoung/p/socket_1.html

参考 https://blog.csdn.net/a19990412/article/details/80919703

参考:https://www.cnblogs.com/xiaokang01/p/9069048.html

方法一:

接收

fileinfo_size=struct.calcsize('128sl')
        buf = conn.recv(fileinfo_size)
        if buf:
            filename, filesize = struct.unpack('128sl', buf)
            fn = filename.decode().strip('0')                             #Python strip() 方法用于删除字符串头部和尾部指定的字符,默认字符为所有空字符,包括空格、换行(
)、制表符(	)等。
            new_filename = os.path.join('./', 'new_' + fn)
            print ('file new name is {0}, filesize is {1}'.format(new_filename,
                                                                 filesize))

            recvd_size = 0  # 定义已接收文件的大小
            fp = open(new_filename, 'wb')
            print ('start receiving...')

            while not recvd_size == filesize:
                if filesize - recvd_size > 1024:
                    data = conn.recv(1024)
                    recvd_size += len(data)
                else:
                    data = conn.recv(filesize - recvd_size)
                    recvd_size = filesize
                fp.write(data)
            fp.close()
            print ('end receive...')

发送:

get_screen(in_pathscr)
               filepath = in_pathscr
               if os.path.isfile(filepath):
                   fileinfo_size = struct.calcsize('128sl')
                   fhead = struct.pack('128sl', bytes(os.path.basename(filepath).encode()),os.stat(filepath).st_size)  #encode很重要
                   s.send(fhead)
                   print ('client filepath: {0}'.format(filepath))  #
                   fp = open(filepath, 'rb')  # rb 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
                   while 1:
                       data = fp.read(1024)
                       if not data:
                           print ('{0} file send over...'.format(filepath))
                           break
                       s.send(data)

方法二

客户端

#!/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 = (('127.0.0.1', 8080))
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()

服务端

#!/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 = (('127.0.0.1', 8080))
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()

        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('发送成功')
原文地址:https://www.cnblogs.com/lqerio/p/11087424.html