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('\00')                             #Python strip() 方法用於刪除字符串頭部和尾部指定的字符,默認字符為所有空字符,包括空格、換行(\n)、制表符(\t)等。
            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('發送成功')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM