客户端代码:
#-*-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(0, 0) 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(fileFullPath, threadIndex, fileSize): 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(0, 0) return fileLength
def writeFilePart(threadCount, fileName, fileSize, clientSocket): 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(fileName, threadCount): 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 |
运行结果示例:
服务器端:
客户端(服务器端做了端口映射:59999->9999):