Python下Socket实现上传下载文件

下列代码实现在客户端上传、下载和浏览服务器文件

运行环境:ubuntu16.04python3.5

服务端IP:192.168.1.8            开放端口号:4518

服务端代码:

###################################################################
#*- 								-*#
#*- coding	: UTF-8 	        			-*#
#*- function	: servicer                                 	-*#
#*- localhost	: 192.168.1.8 					-*#
#*- port	: 4518 						-*#
#*- author	: pwn_w			        		-*#
#*-			 					-*#
###################################################################

import socket,time,socketserver,struct,os

host='192.168.1.8'                                              #本机IP地址
port=4518                                                       #使用的端口
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 		#定义socket类型
s.bind((host,port))						#绑定需要监听的Ip和端口号,tuple格式
s.listen(1)


#--------------------------------接收文件---------------------------------#
def receiverFile(connection,address):				
        try:
            filename = str(conn.recv(1024),encoding="utf8")
            print('Get filename',filename)
            conn.sendall(bytes(filename,encoding="utf8"))
            connection.settimeout(600)
            fileinfo_size=struct.calcsize('128sl') 
            buf = connection.recv(fileinfo_size)
            if buf: #如果不加这个if,第一个文件传输完成后会自动走到下一句
                filename,filesize =struct.unpack('128sl',buf) 
                filename=filename.decode('utf-8')
                filename_f = filename.strip('\00')
                filenewname = os.path.join('/home/pwn_w/',(filename_f))
                print ('file new name is %s, filesize is %s' %(filenewname,filesize))	

                recvd_size = 0 #定义接收了的文件大小
                file = open(filenewname,'wb')
	
                print ('start receiving...')
                while not recvd_size == filesize:
                    if filesize - recvd_size > 1024:
                        rdata = connection.recv(1024)
                        recvd_size += len(rdata)
                    else:
                        rdata = connection.recv(filesize - recvd_size) 
                        recvd_size = filesize
                    file.write(rdata)
                file.close()
                print ('receive done')
        except socket.timeout:
            connection.close()		
#-------------------------------------------------------------------------#


#--------------------------------发送文件---------------------------------#
def sendFile(connection,address):
    value = 'Y'
    filepath = str(conn.recv(1024),encoding="utf8")
    print('Get filename',filepath)
    if os.path.isfile(filepath):
        connection.sendall(bytes(str(value),encoding="utf8"))	
        fileinfo_size=struct.calcsize('128sl') #定义打包规则
        #定义文件头信息,包含文件名和文件大小
        fhead = struct.pack('128sl',os.path.basename(filepath).encode('utf-8'),os.stat(filepath).st_size)
        connection.send(fhead) 
        print ('client filepath: ',filepath)
        fo = open(filepath,'rb')
        while True:
            filedata = fo.read(1024)
            if not filedata:
                break
            connection.send(filedata)
        fo.close()
        print ('send over...')
        #s.close()
    else:
        value = 'N'
        connection.sendall(bytes(str(value),encoding="utf8"))
        print ('no such file')

#-------------------------------------------------------------------------#



#--------------------------------浏览文件---------------------------------#

def scanFile(connection,address):
    filepath = str(conn.recv(1024),encoding="utf8")
    result = []
    value = 'Y'
    if os.path.isfile(filepath):
        connection.sendall(bytes(str(value),encoding="utf8"))
        for maindir,subdir,file_name_list in os.walk(filepath):
            for filename in file_name_list:
                apath = os.path.join(maindir,filename)
                result.append(apath)
            connection.sendall(bytes(str(result),encoding="utf8"))
    else:
        value = 'N'
        connection.sendall(bytes(str(value),encoding="utf8"))

#-------------------------------------------------------------------------#


#--------------------------------执行函数---------------------------------#

def work():
    mode = str(conn.recv(1024),encoding="utf8")			#获取工作模式
    if (mode=='D'):						#进入发送函数
        sendFile(conn,addr)
    elif(mode=='U'):						#进入接收函数
        receiverFile(conn,addr)
    elif(mode=='S'):
        scanFile(conn,addr)	
    elif(mode=='Q'):						#退出
        exit(0)
    else:							#输入其他则提示重新输入
        print('Get an invalid value, waiting next data...')    

#-------------------------------------------------------------------------#



while True:
    conn,addr = s.accept()					#创建套接字
    print('Connected by ',addr)					#打印套接字信息
    while True:
        work()												
    conn.close()	

客户端代码:

###########################################################################
#*- 									-*#
#*- 	coding		: UTF-8 					-*#
#*-	function	: Client                                   	-*#
#*- 	connectHost	: 192.168.1.8 					-*#
#*- 	connectPort	: 4518 						-*#
#*-	author		: pwn_w						-*#
#*-			 						-*#
###########################################################################

import os,struct
from socket import *
s = socket(AF_INET,SOCK_STREAM)							#定义socket类型
s.connect(('192.168.1.8',4518))							#创建连接

#--------------------------------发送文件---------------------------------#
def sendFile():															
    filepath = input('Input the video you want to send:\r\n')
    s.sendall(bytes(filepath,encoding="utf8"))
    filepath = str(s.recv(1024), encoding="utf8")
    if os.path.isfile(filepath):
        fileinfo_size=struct.calcsize('128sl') 
        fhead = struct.pack('128sl',os.path.basename(filepath).encode('utf-8'),os.stat(filepath).st_size)
        s.send(fhead) 
        print ('client filepath: ',filepath)
        fo = open(filepath,'rb')
        while True:
            filedata = fo.read(1024)
            if not filedata:
                break
            s.send(filedata)
        fo.close()
        print ('send over...')
    else:
        print ('no such file')
#-------------------------------------------------------------------------#

#--------------------------------接收文件----------------------------------#
def receiverFile():
        try:
            filename = input('Which file you want to download:\r\n')		#输入要下载的文件
            s.sendall(bytes(filename,encoding="utf8"))
            s.settimeout(600)
            isFile = str(s.recv(1024),encoding = "utf8")
            print('isFile:',isFile)
            if isFile == 'Y':
                fileinfo_size=struct.calcsize('128sl')				#打包规则
                buf = s.recv(fileinfo_size)
                if buf:
                    filename,filesize =struct.unpack('128sl',buf) 
                    filename=filename.decode('utf-8')
                    filename_f = filename.strip('\00')
                    filenewname = os.path.join('/home/aston/',(filename_f))
                    print ('file new name is %s, filesize is %s' %(filenewname,filesize))	

                    recvd_size = 0 #定义接收了的文件大小
                    file = open(filenewname,'wb')
	
                    print ('stat receiving...')
                    while not recvd_size == filesize:
                        if filesize - recvd_size > 1024:
                            rdata = s.recv(1024)
                            recvd_size += len(rdata)
                        else:
                            rdata = s.recv(filesize - recvd_size) 
                            recvd_size = filesize
                        file.write(rdata)
                    file.close()
                    print ('receive done')
        except socket.timeout:
                print('timeout')
#-------------------------------------------------------------------------#



#--------------------------------浏览文件----------------------------------#

def scanFile():
    directory = input('Which directory you want to scan:\r\n')    
    s.sendall(bytes(directory,encoding="utf8"))
    isFile = str(s.recv(1024),encoding = "utf8")
    if isFile == 'Y':
        acceptFile = str(s.recv(1024),encoding = "utf8")
        print("".join(("List:",acceptFile)))
    else:
        print('ERROR: THE SERVER WITHOUT THIS PATH...')

#-------------------------------------------------------------------------#



	
#--------------------------------执行函数----------------------------------#

def work():
    Mode = input('Upload(U)、Download(D)、Scan(S) or Quit(Q):\r\n')		#输入工作模式
    s.sendall(bytes(Mode,encoding="utf8"))					#发送至工作模式至服务器
	
    if  (Mode=='D'):								#下载文件
        receiverFile()
    elif(Mode=='U'):								#上传文件
        sendFile()
    elif(Mode=='S'):
        scanFile()
    elif(Mode=='Q'):				    #退出服务器
        exit(0)
    else:					    #提示输入错误工作模式
        print('Invalid value, please input again...')


#-------------------------------------------------------------------------#
				
while True:		
    work()
s.close()


猜你喜欢

转载自blog.csdn.net/wg_rui/article/details/80027908