python socket 傳輸文件


推薦資料

https://www.cnblogs.com/xiaokang01/p/9865724.html

socket傳輸文件

思路:
        #   先將報頭轉換成字符串(json.dumps), 再將字符串的長度打包
        #   發送報頭長度,發送報頭內容,最后放真是內容
        #   報頭內容包括文件名,文件信息,報頭
        #   接收時:先接收4個字節的報頭長度,
        #   將報頭長度解壓,得到頭部信息的大小,在接收頭部信息, 反序列化(json.loads)
        #   最后接收真實文件

服務端

#!/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('發送成功')

客戶端

#!/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 下午3:44
# @Author  : LK
# @File    : 進度條.py
# @Software: PyCharm
import sys
import time
def process_bar(precent, width=50):
    use_num = int(precent*width)
    space_num = int(width-use_num)
    precent = precent*100
    #   第一個和最后一個一樣梯形顯示, 中間兩個正確,但是在python2中報錯
    #
    # print('[%s%s]%d%%'%(use_num*'#', space_num*' ',precent))
    # print('[%s%s]%d%%'%(use_num*'#', space_num*' ',precent), end='\r')
    print('[%s%s]%d%%'%(use_num*'#', space_num*' ',precent),file=sys.stdout,flush=True, end='\r')
    # print('[%s%s]%d%%'%(use_num*'#', space_num*' ',precent),file=sys.stdout,flush=True)

# for i in range(21):
#     precent = i/20
#     process_bar(precent)
#     time.sleep(0.2)

 

 

socket_server 傳輸文件 

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-5-21 下午8:04
# @Author  : LK
# @File    : server_socket_文件_服務端.py
# @Software: PyCharm

import socketserver
import struct

import os
import json
import struct


def sendRealFile(conn, filename):
    '''發送真是文件'''
    with open(filename, 'rb')as f:
        conn.sendall(f.read())

    print('發送成功')


def operafile(filename):
    '''對報頭進行打包'''
    filesize_bytes = os.path.getsize(filename)
    head_dir = {
        'filename': 'new' + filename,
        'filesize_bytes': filesize_bytes,
    }
    head_info = json.dumps(head_dir)
    head_info_len = struct.pack('i', len(head_info))
    return head_info_len, head_info

class MyServer(socketserver.BaseRequestHandler):
    buffsize = 1024
    def handle(self):
        # self.request
        print('連接人的信息')
        print('conn是', self.request)  # conn
        print('addr是', self.client_address)  # addr

        while True:
            '''收發消息'''
            filename = input('請輸入要發送的文件名加上后綴>>>').strip()
            #   判斷文件是否存在

            head_info_len, head_info = operafile(filename)
            self.request.send(head_info_len)  # 這里是4個字節
            self.request.send(head_info.encode('utf-8'))  # 發送報頭的內容
            sendRealFile(self.request, filename)


if __name__ == '__main__':
    # pass
    print('還沒有人連接')
    s = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)  # 多線程
    #   服務器一直開着
    s.serve_forever()
socket_server傳輸文件服務端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 18-5-21 下午8:32
# @Author  : LK
# @File    : server_socket_文件客戶端.py
# @Software: PyCharm
from socket import *
import os
import sys
import json
import struct

tcp_client = socket(AF_INET, SOCK_STREAM)
ip_port = (('127.0.0.1', 8080))
buffsize = 1024
tcp_client.connect_ex(ip_port)
print('等待服務端發送信息')


def recv_file(head_dir, tcp_client):
    filename = head_dir['filename']
    filesize_b = head_dir['filesize_bytes']
    recv_len = 0
    recv_mesg = b''
    f = open(filename, 'wb')
    while recv_len < filesize_b:
        if filesize_b - recv_len > buffsize:
            recv_mesg = tcp_client.recv(buffsize)
            recv_len += len(recv_mesg)
            f.write(recv_mesg)
        else:
            recv_mesg = tcp_client.recv(filesize_b - recv_len)
            recv_len += len(recv_mesg)
            f.write(recv_mesg)

    f.close()
    print('文件傳輸完成')

while True:
    '''收發循環'''
    struct_len = tcp_client.recv(4)  #  接受報頭的長度
    struct_info_len = struct.unpack('i',struct_len)[0]  #   解析得到報頭信息的長度
    head_info = tcp_client.recv(struct_info_len)   #    接受報頭的內容
    head_dir = json.loads(head_info.decode('utf-8'))              #   將報頭的內容反序列化
    # #   文件信息
    # filename = head_dir['filename']
    # filesize = head_dir['filesize_bytes']
    recv_file(head_dir, tcp_client)

    #   接受文件
socket_server傳輸文件客戶端

 


免責聲明!

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



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