zoukankan      html  css  js  c++  java
  • 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('发送成功')
  • 相关阅读:
    ZOJ 2158 Truck History
    Knight Moves (zoj 1091 poj2243)BFS
    poj 1270 Following Orders
    poj 2935 Basic Wall Maze (BFS)
    Holedox Moving (zoj 1361 poj 1324)bfs
    ZOJ 1083 Frame Stacking
    zoj 2193 Window Pains
    hdu1412{A} + {B}
    hdu2031进制转换
    openjudge最长单词
  • 原文地址:https://www.cnblogs.com/lqerio/p/11087424.html
Copyright © 2011-2022 走看看