基于C/S的网盘设计(JAVA) - 网盘源码-实现部分功能

基于C/S的网盘设计(JAVA) - 网盘源码-实现部分功能

 

由于有其他的工作,网盘做了一部分不得不放手了,

我希望有时间的其他朋友可以继续工作,虽然网络上有很多现成的网盘代码,不过还是希望自己能做一个,并借鉴一些优秀的思想来实现,下面说下实现过程,有些部分需要改进

一、数据库的设计,目前只涉及到用户表,当然还有其他的,你可以根据需要来增加

#用户表
create table m_user(
 id int primary key auto_increment,
 name varchar(32) not null unique,
 password char(32) not null,
 `gender` enum('男','女') NOT NULL DEFAULT '男',
 phone varchar(20),
 email varchar(50) not null,
 reg_date char(16) not null,
 reg_ip varchar(15) not null,
 last_login_date char(16),
 last_login_ip varchar(15)
);

 

二、数据源的设置,我这里使用c3p0数据源,当然你可以使用dbcp或者其他的

配置c3p0-config.xml文件就可以了,网络上有详细的配置项,或者在我源码里面下载,在最后公布下载地址

在这里我写一个简单的JdbcUtil,当然还可以编写一些复杂的操作,工作不允许我继续往下写了,你可以集成一些操作,就像hibernate那样

复制代码
public class JdbcUtil {    /**     * 数据库连接管理器     *///    private static Logger log = Logger.getLogger(JdbcUtil.class);    /*初始化数据库连接池*/    private static DataSource dataSource = new ComboPooledDataSource();        /*获取数据源*/    public DataSource getDataSource(){        return dataSource;    }        /*获取连接*/    public static Connection getConnection() throws SQLException{        return dataSource.getConnection();    }        /*释放连接*/    public static void free(ResultSet rs,PreparedStatement ps,Connection conn){        if(null != rs){            try {                rs.close();            } catch (SQLException e) {}        }        if(null != ps){            try {                ps.close();            } catch (SQLException e) {}        }        if(null != conn){            try {                conn.close();            } catch (SQLException e) {}        }    }    public static void free(PreparedStatement ps,Connection conn){        if(null != ps){            try {                ps.close();            } catch (SQLException e) {}        }        if(null != conn){            try {                conn.close();            } catch (SQLException e) {}        }    }}
复制代码


三、我这里先说说服务端

1.socket线程池

池的作用想必大家都知道,循环利用资源,我这里的这个池只是简单的池,没有时间再完成一个复杂的工作了

cn.mike.server.ServerThread是一个负责处理用户请求的线程,我们要创建一批这样的线程,并由cn.mike.server.ServerThreadPool管理,代码如下:

复制代码
public class ServerThreadPool {    /**     * 服务端线程池     */    private final static Logger log = Logger.getLogger(ServerThreadPool.class);    //线程组    public static LinkedList<ServerThread> threadPool = new LinkedList<ServerThread>();    private static int maxPoolSize;//最大连接数    private static int minPoolSize;//最小连接数    private static int initialPoolSize;//初始化连接数    private static int maxIdleTime;//连接的最大空闲时间,单位:秒    private static int acquireIncrement;//在当前连接数耗尽的时候,一次获取的新的连接数    static int maxWaitUserTime;//线程等待用户操作的最大时间,到达最大时间未传送数据,则进行线程释放        public ServerThreadPool(){        initProperties();        initThreadPool();    }        /*     * 初始化配置     */    public void initProperties(){        System.out.println("正在启动线程池...");        System.out.println("正在加载线程池配置文件...");        Properties pro = new Properties();        HashMap<String, String> propertiesMap = new HashMap<String, String>();        try {            pro.load(ServerThreadPool.class.getClassLoader().getResourceAsStream(ServerThreadPoolConfig.PROPS_FILE_RSRC_PATH));            propertiesMap.put(ServerThreadPoolConfig.MAX_POOL_SIZE, pro.getProperty(ServerThreadPoolConfig.MAX_POOL_SIZE));            propertiesMap.put(ServerThreadPoolConfig.MIN_POOL_SIZE, pro.getProperty(ServerThreadPoolConfig.MIN_POOL_SIZE));            propertiesMap.put(ServerThreadPoolConfig.INITIAL_POOL_SIZE, pro.getProperty(ServerThreadPoolConfig.INITIAL_POOL_SIZE));            propertiesMap.put(ServerThreadPoolConfig.MAX_IDLE_TIME, pro.getProperty(ServerThreadPoolConfig.MAX_IDLE_TIME));            propertiesMap.put(ServerThreadPoolConfig.ACQUIRE_INCREMENT, pro.getProperty(ServerThreadPoolConfig.ACQUIRE_INCREMENT));            propertiesMap.put(ServerThreadPoolConfig.MAX_WAIT_USER_TIME, pro.getProperty(ServerThreadPoolConfig.MAX_WAIT_USER_TIME));            if(null != propertiesMap.get(ServerThreadPoolConfig.MAX_POOL_SIZE)){                ServerThreadPool.maxPoolSize = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.MAX_POOL_SIZE));            }else{                ServerThreadPool.maxPoolSize = 100;            }                        if(null != propertiesMap.get(ServerThreadPoolConfig.MIN_POOL_SIZE)){                ServerThreadPool.minPoolSize = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.MIN_POOL_SIZE));            }else{                ServerThreadPool.minPoolSize = 5;            }                        if(null != propertiesMap.get(ServerThreadPoolConfig.INITIAL_POOL_SIZE)){                ServerThreadPool.initialPoolSize = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.INITIAL_POOL_SIZE));            }else{                ServerThreadPool.initialPoolSize = 5;            }                        if(null != propertiesMap.get(ServerThreadPoolConfig.MAX_IDLE_TIME)){                ServerThreadPool.maxIdleTime = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.MAX_IDLE_TIME));            }else{                ServerThreadPool.maxIdleTime = 10;            }                        if(null != propertiesMap.get(ServerThreadPoolConfig.ACQUIRE_INCREMENT)){                ServerThreadPool.acquireIncrement = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.ACQUIRE_INCREMENT));            }else{                ServerThreadPool.acquireIncrement = 1;            }            if(null != propertiesMap.get(ServerThreadPoolConfig.MAX_WAIT_USER_TIME)){                ServerThreadPool.maxWaitUserTime = Integer.parseInt(propertiesMap.get(ServerThreadPoolConfig.MAX_WAIT_USER_TIME));            }else{                ServerThreadPool.maxWaitUserTime = 60000;            }                    } catch (Exception e) {            log.error("线程池配置文件加载出错,请确保文件threadPool.properties存在,并正确配置!");            System.exit(1);        }        System.out.println("线程池配置加载成功,配置信息如下:");        System.out.println("#################################");        System.out.println("最大连接数:"+ServerThreadPool.maxPoolSize);        System.out.println("最小连接数:"+ServerThreadPool.minPoolSize);        System.out.println("初始化连接数:"+ServerThreadPool.initialPoolSize);        System.out.println("连接的最大空闲时间:"+ServerThreadPool.maxIdleTime+" 秒");        System.out.println("在当前连接数耗尽的时候,一次获取的新的连接数:"+ServerThreadPool.acquireIncrement);        System.out.println("线程等待用户操作的最大时间:"+ServerThreadPool.maxWaitUserTime+" 毫秒");        System.out.println("#################################");    }    /*     * 初始化服务线程     */    public void initThreadPool(){        for(int i=0;i<ServerThreadPool.initialPoolSize;i++){            ServerThread st = new ServerThread();            st.start();            threadPool.add(st);        }    }        /*     * 线程池动态调整器     */    public void poolAdjust(){            }}
复制代码


一些配置规范我把它放在cn.mike.server.ServerThreadPoolConfig里

复制代码
public class ServerThreadPoolConfig {    /*     * 线程池配置     */        //配置文件路径    public final static String PROPS_FILE_RSRC_PATH     = "threadPool.properties";    //最大连接数    public final static String MAX_POOL_SIZE = "maxPoolSize";    //最小连接数    public final static String MIN_POOL_SIZE = "minPoolSize";    //初始化连接数    public final static String INITIAL_POOL_SIZE= "initialPoolSize";    //连接的最大空闲时间,单位:秒    public final static String MAX_IDLE_TIME = "maxIdleTime";    //在当前连接数耗尽的时候,一次获取的新的连接数    public final static String ACQUIRE_INCREMENT = "acquireIncrement";    //线程等待用户操作的最大时间,到达最大时间未传送数据,则进行线程释放    public final static String MAX_WAIT_USER_TIME = "maxWaitUserTime";    }
复制代码

threadPool.properties文件用于配置线程池的一些选项,我这里的设置可能不够完整,你可以根据需要增加

还有一个重要问题,这里需要开启一个线程来管理线程池里线程的数量,实现动态调整,这工作我并没完成,希望你能把它完成

cn.mike.server.Server是一个用于接收用户请求的分配器,处理一些初始化工作

复制代码
public class Server {    /**     * 25米 网盘 服务端     */    private final static Logger log = Logger.getLogger(Server.class);    private int listenPort = 8594;//监听端口    private static ServerSocket ss;    static LinkedList<Socket> taskQueue = new LinkedList<Socket>();//任务队列    public static Map<String,Session> sessionMap = new HashMap<String,Session>();    /*初始化线程池*/    ServerThreadPool stp = new ServerThreadPool();    /*数据库连接工具*/    public JdbcUtil jdbcUtil = new JdbcUtil();    private int maxWaitUserTime = ServerThreadPool.maxWaitUserTime;//最大等待操作时间        public static void main(String[] args) {        System.out.println("正在启动服务器...");        Server server = new Server();        new TaskHandle().start();        server.init();    }    public void init(){//        初始化数据库连接池        System.out.println("正在初始化数据库连接池...");        try {            System.out.println("#################################");            JdbcUtil.getConnection().close();            System.out.println("#################################");            System.out.println("数据库连接池创建成功!");        } catch (SQLException e1) {            log.error("数据库连接池创建失败!");            System.exit(1);        }                /*开启监听服务*/        try {            ss = new ServerSocket(listenPort);            System.out.println("服务器启动成功,正在监听端口:"+listenPort);            while(true){                Socket socket = ss.accept();                socket.setSoTimeout(maxWaitUserTime);//设置最大连接时长                System.out.println("发现客户端连接,IP:"+socket.getRemoteSocketAddress());                process(socket);//转入线程池处理            }        } catch (IOException e) {            System.out.println("服务器启动失败,请确保端口:"+listenPort+"不被其他程序占用!");        }    }        /*     * 服务线程处理客户端请求     */    public void process(Socket socket){        if(ServerThreadPool.threadPool.size()>0){//如果池中还有服务线程            ServerThreadPool.threadPool.removeFirst().startWork(socket);        }        else if(taskQueue.size()<1000){//若没有,并且队列长度小于1000,则加入任务队列            taskQueue.add(socket);        }        else{            try {                socket.close();            } catch (IOException e) {                log.error("关闭客户端socket失败!");            }        }    }    }/* *开启定时器,处理任务队列,每隔 500 毫秒查看有没有空闲连接 */class TaskHandle extends Thread{    static LinkedList<Socket> taskQueue =  Server.taskQueue;    public TaskHandle(){        System.out.println("队列任务处理器开启..");    }    public void run() {        try {            while(true){                Thread.sleep(500);                if(taskQueue.size()>0 && ServerThreadPool.threadPool.size()>0){//如果池中还有服务线程,则处理任务队列                    ServerThreadPool.threadPool.removeFirst().startWork(Server.taskQueue.removeFirst());                }            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }    }
复制代码

 

可能有些东西读者不是很明白,这需要对socket编程熟悉点,当然我的设计也有些问题,希望读者能提改进意见,有时间就修改

服务端启动如下:

 

四、下面说说客户端

客户端就是登陆界面和管理网盘界面

1.登陆界面:cn.mike.client.ClientLogin

不是很漂亮,勉强用着吧,当然你可以设计得漂亮点

登陆成功后是这样的:

大概做到这里了,数据的上传下载等没时间实现了,感兴趣的朋友可以继续我的工作

源码我放到CSDN下面:http://download.csdn.net/detail/mzlqh/4514886

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
盘修复的核心功能: 1.断点续传功能。市面上许多所谓的断点传传基本没有完美的,本源码经过修复,完美实现了断点、续传功能。 切片:大文件分成1MB大小的小文件, 服务器上传无压力,切片文件合并无压力。市面上许多切片文件合并时CPU经常占用99%,本源码CPU没有任何压力。 续传:上传中间如果人工或络出现故障,再上传时会接着上传,不会像上的许多所谓的续传,全是从0开始。: 2.极速上传。由于采取了优化过的代码,WEB上传速度可媲美flashfxp等专业上传软件,稳定,极速。 3.强大的垃圾文件删除功能。如果大文件中途停止上传,今后再不上传的话,系统会产生若干垃圾切片文件,本系统会自动监测,如7天后会自动删除切片垃圾文件,释放服务器空间。 4.支持ssl功能,可直接用https://形式访问。 5.强大的定时任务。本系统会定时清理盘回收站垃圾文件,而这一功能完全由系统完成,不需要由像其它系统一样必须在第三方定时设置定时任务。 盘主要功能: 1.支持用户管理系统。支持用户注册功能(后台可关闭),管理可为每个用户分配一定数额的存储空间,还可以限制单个上传文件大小。 2.支持管理员查看每个会员的文件上传、分享情况,可对用户文件进行删除等管理。目前,市面上的便宜盘基本都只支持个人功能,没有管理员功能,无法管理其它用户的文件。 3.支持强大的分享功能。 提取密码:输入正确的提取码方可下载文件 分享次数:超次分享次数,文件就无法下载(百度盘没有这个功能) 分享日期:在设置的日期段内可进行下载。 4.响应式设计,完美支持手机、平板等移动终端设备。 5.可灵活设置群组权限,可只允许查看、编辑等功能。(类似于QQ群概念一样,进入群组的人可以像共享文件夹一样分享、共享、下载文件,可设置权限,如群组创建者可设置群组成员只允许查看、下载文件,但不允许其它人员上传分享文件) 6.支持压缩包在线查看功能。直接在线查看,不用下载直接在线解压。 7.支持在线创建文件夹、创建文件,删除文件等操作。 8.支持office文件在线预览功能,相当牛比。 9.支持mp4 mp3文件在线预览播放功能。 10.支持极速上传文件功能。本盘采取html上传技术,在WEB上传速度完全可媲美FLASHFXP等专业上传软件。 11.真正的断点续传功能,市面上许多所谓的断点续传功能都有问题。你将一个5G大文件上传到50%后,人为中断,再重新上传看看,基本全从0开始了,本盘可接着从50%上传。 12.密码找回功能,如果忘记密码,可通过邮箱找回。 13.支持大文件体积识别功能。市面上许多上传程序,对超过2G的文件全识别为0或者几百MB,造成文件下载时出错。 14.垃圾切片文件自动删除功能。有些会员上传大文件过程中,可能由于人为或络的问题,没有将文件上传到100%,之后再没有上传文件,造成产生了许多垃圾切片文件。本系统可智能删除垃圾切片文件,尽可能利用服务器空间。 15.自动删除回收站功能。本盘可设置N天自动删除回收站文件,对于删除的文件会自动进入回收站,对进入回收站的文件,超过设置的天数会自动进行删除。不仅删除数据库记录,更会自动删除服务器上的物理文件。许多盘都无法删除服务器上的文件,只是删除了数据库记录,并没有真正删除服务器文件,造成资源严重浪费。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值