python多线程文件传输范例(C/S)

来源:互联网 发布:杭州程序员招聘信息 编辑:程序博客网 时间:2024/05/15 07:03


客户端代码:

#-*-encoding:utf-8-*-

 

import socket

import os

import sys

import math

import time

import threading

 

def getFileSize(file):

    file.seek(0, os.SEEK_END)

    fileLength = file.tell()

    file.seek(00)

    return fileLength

 

def getFileName(fileFullPath):

    index = fileFullPath.rindex('\\')

    if index == -1:

        return fileFullPath 

    else:

        return fileFullPath[index+1:]

 

def transferFile():

    fileFullPath = r"%s" % raw_input("File path: ").strip("\"")

    if os.path.exists(fileFullPath):

        timeStart = time.clock()

        file = open(fileFullPath, 'rb')

        fileSize = getFileSize(file)

        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        client.connect((targetHost, targetPort))

        # send file size

        client.send(str(fileSize))

        response = client.recv(1024)

        # send file name

        client.send(getFileName(fileFullPath))

        response = client.recv(1024)

        # send thread count

        client.send(str(threadCount))

        response = client.recv(1024)

        # send file content

        for i in range(threadCount):

            filePartSender = threading.Thread(target=transferFileSubThread, args=(fileFullPath, i+1, fileSize))

            filePartSender.start()

        

        for i in range(threadCount):

            sem.acquire()

        timeEnd = time.clock()

        print "Finished, spent %f seconds" % (timeEnd - timeStart)

    else:

        print "File doesn't exist"

 

def transferFileSubThread(fileFullPaththreadIndexfileSize):

    try:

        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        client.connect((targetHost, targetPort))

        client.send(str(threadIndex))

        client.recv(1024)

        # calculate start position and end position

        filePartSize = fileSize / threadCount

        startPosition = filePartSize * (threadIndex - 1)

        #print "Thread : %d, startPosition: %d" % (threadIndex, startPosition)

        endPosition = filePartSize * threadIndex - 1

        if threadIndex == threadCount:

            endPosition = fileSize - 1

            filePartSize = fileSize - startPosition

        file = open(fileFullPath, "rb")

        file.seek(startPosition)

        sentLength = 0

        while sentLength < filePartSize:

            bufLen = 1024

            lengthLeft = filePartSize - sentLength

            if lengthLeft < 1024:

                bufLen = lengthLeft

            buf = file.read(bufLen)

            client.send(buf)

            sentLength += len(buf)

        file.close()

        sem.release()

        print "Part %d finished, size sent %d" % (threadIndex, sentLength)

    except Exception, e:

        print e

 

targetHost = raw_input("Server IP Address: ")

targetPort = int(raw_input("Server port: "))

threadCount = int(raw_input("Thread count: "))

sem = threading.Semaphore(0)

 

while True:

    transferFile()

 

服务器端代码:

#-*-encoding:utf-8-*-

 

import socket

import threading

import os

import sys

import math

import time

 

bindIp = "0.0.0.0"

bindPort = 9999

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind((bindIp, bindPort))

server.listen(20)

print "Listening on %s:%d" % (bindIp, bindPort)

 

def getFileSize(file):

    file.seek(0, os.SEEK_END)

    fileLength = file.tell()

    file.seek(00)

    return fileLength

 

def writeFilePart(threadCountfileNamefileSizeclientSocket):

    try:

        threadIndex = int(clientSocket.recv(1024))

        clientSocket.send("Received")

        filePartName = fileName + str(threadIndex)

        filePartSize = fileSize / threadCount

        lengthToWrite = filePartSize

        if threadIndex == threadCount:

            lengthToWrite = fileSize - filePartSize * (threadCount - 1)

        file = open(filePartName, "wb")

        receivedLength = 0

        while receivedLength < lengthToWrite:

            bufLen = 1024

            buf = clientSocket.recv(bufLen)

            file.write(buf)

            receivedLength += len(buf)

        file.close()

        sem.release()

        #print "thread %d finished, size received %d" % (threadIndex, receivedLength)

    except Exception, e:

        print e

 

def checkFileName(originalFileName):

    extensionIndex = originalFileName.rindex(".")

    name = originalFileName[:extensionIndex]

    extension = originalFileName[extensionIndex+1:]

    

    index = 1

    newNameSuffix = "(" + str(index) + ")"

    finalFileName = originalFileName

    if os.path.exists(finalFileName):

        finalFileName = name + " " + newNameSuffix + "." + extension

    while os.path.exists(finalFileName):

        index += 1

        oldSuffix = newNameSuffix

        newNameSuffix = "(" + str(index) + ")"

        finalFileName = finalFileName.replace(oldSuffix, newNameSuffix)

    return finalFileName

 

def writeFile(fileNamethreadCount):

    file = open(fileName, "wb")

    for i in range(threadCount):

        filePartName = fileName + str(i+1)

        #print "Reading file %s" % filePartName

        filePart = open(filePartName, "rb")

        filePartSize = getFileSize(filePart)

        lengthWritten = 0

        while lengthWritten < filePartSize:

            bufLen = 1024

            buf = filePart.read(bufLen)

            file.write(buf)

            lengthWritten += len(buf)

        filePart.close()

        os.remove(filePartName)

    file.close()

 

sem = threading.Semaphore(0)

 

while True:

    client, addr = server.accept()

    print "[*] Accepted connection from: %s:%d" % (addr[0], addr[1])

    

    # receive file size

    fileSize = int(client.recv(1024))

    client.send("Received")

    # receive file name

    fileName = client.recv(1024)

    client.send("Received")

    fileName = checkFileName(fileName)

    print "[==>] Saving file to %s" % fileName

    # receive client thread count

    clientThreadCount = int(client.recv(1024))

    client.send("Received")

    for i in range(clientThreadCount):

        clientPartSocket, addrTmp = server.accept()

        filePartWriter = threading.Thread(target=writeFilePart, args=(clientThreadCount, fileName, fileSize, clientPartSocket,))

        filePartWriter.start()

    

    for i in range(clientThreadCount):

        sem.acquire()

    writeFile(fileName, clientThreadCount)

    print "[==>] Saved to file %s" % fileName

 

运行结果示例:

服务器端:

_ Administrator: - python FileTransferServerMuItiThread.py Microsoft Windows [Uersion 6 ] opyright (c) 2009 Microsoft Corporation . All rights reserved. Desktop Filer ransFerSeruerMuItiThread.py Listening on ø.ø.ø.ø:9999 Accepted connection From: 39 .155 .188 .33: 30203 Saving File to Saved to File Accepted connection From: 39 .155 .188 .33:533ø Saving File to .3.2. exe Saved to File Accepted connection From: 39 .155 .188 .33:5883 Saving File to .3.2. exe Saved to File

 

客户端(服务器端做了端口映射:59999->9999):

- python FileTransferCIientMuItiThread.py D: Fil eTransferC1 i entMu1 tiThread. py Server IP Address: 42. 159. 123. 130 Server port: 59999 Thread count: 20 File Part Part Part Part Part Part Part Part Part Part Part Part Part Part Part Part Part Part Part File path: D: \ Setups\pycharm-professiona1-2016. 3. 2. exe 18 fini shed, 9 fini shed, 10 fini shed, 5 fini shed, 1 fini shed, 2 fini shed, 4 fini shed, 14 fini shed, 6 fini shed, 16 fini shed, 3 fini shed, size sent 12181724Part 8 fini shed, size sent size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 size sent 12181724 12181724 15 13 19 17 12 11 20 fini shed, fini shed, fini shed, fini shed, fini shed, fini shed, fini shed, size size size size size size size sent sent sent sent sent sent sent 12181724 12181724 12181724 12181724 12181724 12181724 12181724 7 fini shed, path: size sent 12181724Finished, spent 223. 545544 seconds

 

14 0