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



客户端代码:

#-*-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

 

运行结果示例:

服务器端:

python多线程文件传输范例(C/S)_第1张图片

 

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

python多线程文件传输范例(C/S)_第2张图片

 

你可能感兴趣的:(Windows,Python,Script,Programming,程序设计,计算机网络)