FTP 上传下载 python 代码实现

环境:Ubuntu python3.5  sublime

模块:socket

网络编程方面知识

服务端

# coding=gbk
from socket import *
import os 
import sys
import signal 
import time

FILE_PATHi = "/home/exercise/"
FILE_PATHii = "/home/exercise/FTP/"

class FtpServer(object):
    def __init__(self,connfd):
        self.connfd = connfd

    def do_list(self):
        filelist = os.listdir(FILE_PATHi)
        if filelist == None:
            self.connfd.send(b"FALL") 
        self.connfd.send(b'OK')
        time.sleep(0.1)
        for filename in filelist:
            if filename[0] != '.' and os.path.isfile(FILE_PATHi + filename):
                self.connfd.send(filename.encode())
                time.sleep(0.1)
        self.connfd.send(b"##")
        print('文件列表发送完毕')
        return

    def do_get(self,filename):
        try:
            fd = open(FILE_PATHi+filename,'rb')
        except:
            self.connfd.send(b"FALL") 
        self.connfd.send(b'OK')
        time.sleep(0.1)
        for line in fd:
            self.connfd.send(line)
        fd.close()
        time.sleep(0.1)
        self.connfd.send(b'##')
        print("文件发送成功")
        return

    def do_put(self,filename):
        try:
            fid = open(FILE_PATHii+filename,'rb')
        except:
            self.connfd.send(b"FALL") 
        self.connfd.send(b'OK')
        time.sleep(0.1)
        for line in fid:
            self.connfd.send(line)
        fid.close()
        time.sleep(0.1)
        self.connfd.send(b'##')
        print("文件上传成功")
        return


def main():
    if len(sys.argv) != 3:
        print("argv is error")
        sys.exit(1)
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])
    ADDR = (HOST,PORT)
    BUFFERSIZE = 1024

    sockfd = socket()
    sockfd.bind(ADDR)
    sockfd.listen(5)
    signal.signal(signal.SIGCHLD,signal.SIG_IGN)
    while True:
        try:
            connfd,addr = sockfd.accept()
        except KeyboardInterrupt:
            sockfd.close()
            sys.exit(0)
        except Exception:
            continue
        print("客户端登录:",addr)
        pid = os.fork()
        if pid < 0:
            print("创建子进程失败")
            continue
        elif pid == 0:
            sockfd.close()
            ftp = FtpServer(connfd)
            #接收客户端请求
            while True:
                data = connfd.recv(BUFFERSIZE).decode()
                if data[0] == 'L':
                    ftp.do_list()
                elif data[0] == 'G':
                    filename = data.split(' ')[-1]
                    ftp.do_get(filename)
                elif data[0] == "P":
                    filename = data.split(' ')[-1]
                    ftp.do_put(filename)
                elif data[0] == "Q":
                    print("客户端退出")
                    sys.exit(0)

        else:
            connfd.close()
            continue


if __name__ == "__main__":
    main()

客户端

# coding=gbk
from socket import * 
import sys 

class FtpClient(object):
    def __init__(self,sockfd):
        self.sockfd = sockfd

    def do_list(self):
        self.sockfd.send(b"L") #发送请求类型
        #接收服务器确认 OK  or  FALL
        data = self.sockfd.recv(1024).decode()
        if data == 'OK':
            while True:
                data = self.sockfd.recv(1024).decode()
                if data == '##':
                    break
                print(data)
            print("文件列表展示完毕")
            return
        else:
            print("文件列表请求失败")
            return

    def do_get(self,filename):
        self.sockfd.send(("G " + filename).encode())
        #接收服务器确认 OK  or  FALL
        data = self.sockfd.recv(1024).decode()
        if data == 'OK':
            fd = open(filename,'w')
            while True:
                data = self.sockfd.recv(1024).decode()
                if data == '##':
                    break
                fd.write(data)
            fd.close()
            print('%s 下载完成'%filename)
            return
        else:
            print("下载文件失败")
            return

    def do_put(self,filename):
        self.sockfd.send(("P " + filename).encode())
        #接收服务器确认 OK  or  FALL
        data = self.sockfd.recv(1024).decode()
        if data == 'OK':
            fid = open("/home/tarena/"+filename,'w')
            while True:
                data = self.sockfd.recv(1024).decode()
                if data == '##':
                    break
                fid.write(data)
            fid.close()
            print('%s 下载完成'%filename)
            return
        else:
            print("下载文件失败")
            return

    def do_quit(self):
        self.sockfd.send(b"Q")

def main():
    if len(sys.argv) != 3:
        print("argv is error")
        sys.exit(1)
    HOST = sys.argv[1]
    PORT = int(sys.argv[2])
    ADDR = (HOST,PORT)
    BUFFERSIZE = 1024
    sockfd = socket()
    sockfd.connect(ADDR)

    ftp = FtpClient(sockfd) #生产事件对象

    while True:
        print("********命令选项**********")
        print("******** list************")
        print("******** get file********")
        print("******** put file********")
        print("******** quit************")
        data = input("输入命令>>")
        
        if data[:4] == 'list':
            ftp.do_list()
        elif data[:3] == 'get':
            filename = data.split(' ')[-1]
            ftp.do_get(filename)
        elif data[:3] == 'put':
            filename = data.split(' ')[-1]
            ftp.do_put(filename) 
        elif data[:4] == 'quit':
            ftp.do_quit()
            sockfd.close()
            sys.exit(0) 
        else:
            print("请输出正确命令!!!")
            continue 


if __name__ == "__main__":
    main()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值