• 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('发送成功')
  • 相关阅读:
    一个完整的AjaxPro例子(转)
    sql2000存储过程
    System.Configuration命名空间下找不到ConfigurationManager类
    编译器错误信息: CS0016
    (转)AjaxPro使用说明
    数据库中去逗号的函数
    asp.net 验证码
    sql2005存储过程
    简单控件分页
    身份证号码验证
  • 原文地址:https://www.cnblogs.com/lqerio/p/11087424.html
Copyright © 2020-2023  润新知