`
rikugun
  • 浏览: 350295 次
  • 性别: Icon_minigender_1
  • 来自: 南宁
社区版块
存档分类
最新评论

随手做一个多线程的 CS架构的 文件传输Demo

    博客分类:
  • JAVA
阅读更多
试一下JDK5的多线程编程,附件是代码,下载后改一下后缀名为.tgz

测试环境
OSX 10.5.6
JDK6
JUnit4.5

参考
  Java基于Socket文件传输示例
Java5 多线程实践

Test 图




Server 接口
/**
 *
 * @author rikugun
 */
public interface Server {
    /*
     * 启动服务器
     */
    public void startup();

     /*
     * 停止服务器
     */
    public void stop();

     /*
     * 判断服务器是否正在运行
     * @return boolean 返回服务器是否正在运行
     */
    public boolean isRunning();
}

客户端接口
/**
 *
 * @author rikugun
 */
public interface Client {
    /*
     * 批量获取文件
     * @param String[] 文件名
     * @return boolean 成功获取返回true
     */
    public boolean getFiles(String[] file_names);

    /*
     * 获取单个文件
     * @param String 文件名
     * @return boolean 成功获取返回true
     */
    public boolean getFile(String file_name);
}


服务器进程
/**
 * 服务器进程
 * @author rikugun
 */
public class ServerImpl implements Server,Runnable {

    private static int PORT = 1213;
    private static int MAX_POOL = 10;
    private ServerSocket serverListen;
    private ExecutorService pool;
    private Properties prop;
    private boolean running = false;

    public boolean isRunning() {
        return running;
    }

    public ServerImpl(Properties prop) {
        this.prop = prop;
        PORT = Integer.parseInt(prop.getProperty("server.port"));
        MAX_POOL = Integer.parseInt(prop.getProperty("server.max_pool"));
        pool = Executors.newFixedThreadPool(MAX_POOL);
    }

    public void startup() {
        try {
            serverListen = new ServerSocket(PORT);
            serverListen.setReuseAddress(true);
            running = !serverListen.isClosed();
            while (running) {
                //获取一个连接后启动一个处理线程
                pool.execute(new ServerThread(serverListen.accept(), prop));
                System.out.println("Get a client");
            }
        } catch (IOException ex) {
            Logger.getLogger(ServerImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void stop(){
        if(serverListen!=null){
            try {
                serverListen.close();
                running = serverListen.isClosed();
                 pool.shutdown();
            } catch (IOException ex) {
                Logger.getLogger(ServerImpl.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void run() {
        startup();
    }
}


文件传输线程
/**
 * 传输文件的线程
 * @author rikugun
 */
public class ServerThread implements Runnable {

    private Properties prop;
    private static String dir_name = "files/";
    private Socket sock;
    private DataOutputStream dos;
    private DataInputStream dis;
    private static int buf_size = 8192;
    private static Logger logger = Logger.getLogger(ServerThread.class.getName());

    public ServerThread(Socket sock, Properties prop) {
        this.sock = sock;
        this.prop = prop;
        dir_name = prop.getProperty("server.file_path");
        buf_size = Integer.parseInt(prop.getProperty("server.buf_size"));
    }

    @Override
    public void run() {
        try {
            dos = new DataOutputStream(sock.getOutputStream());
            dis = new DataInputStream(sock.getInputStream());
            //获取文件名
            String file_name = dis.readUTF();
            if (file_name != null) {
                dos.writeBoolean(true);
                logger.log(Level.INFO, "Get the filename:[" + file_name + "],Start to Send file!");
                DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(dir_name +File.separator+ file_name)));
                byte[] buf = new byte[buf_size];
                while (true) {
                    int read = 0;
                    read = fis.read(buf);
                    if (read == -1) {
                        break;
                    }
                    dos.write(buf,0,read);
                }
                dos.flush();
                fis.close();
                logger.log(Level.INFO, "Success Send file:[" + dir_name + file_name + "]");
            } else {
                logger.log(Level.INFO, "No such file named:[" + file_name + "] in [" + dir_name + "]");
                dos.writeBoolean(false);
                dos.writeUTF("No such file named:[" + file_name + "] in [" + dir_name + "]");
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        } finally {
            try {
                dos.close();
            } catch (IOException ex) {
                Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }
}


客户端实现
/**
 *
 * @author rikugun
 */
public class ClientImpl implements Client {

    private Properties prop ;
    private ExecutorService pool;

    public ClientImpl(Properties prop) {
        this.prop = prop;
        pool = Executors.newFixedThreadPool(Integer.parseInt(prop.getProperty("client.max_pool")));
    }
    /*
     * @see csdemo.client.Clinet
     */
    public boolean getFiles(String[] file_names) {
        boolean success = true;
        for (String string : file_names) {
            success = success && getFile(string);
        }
        return success;
    }
    
    /*
     * @see csdemo.client.Clinet
     */
    public boolean getFile(String file_name) {
        boolean success = false;
        try {
            Socket sock = new Socket(prop.getProperty("server.ip"), Integer.parseInt(prop.getProperty("server.port")));
            if(sock.isConnected())System.out.println("Connect to Server");
            //加载处理线程
            pool.execute(new ClientThread(sock, file_name, prop));
            success = true;
        } catch (UnknownHostException ex) {
            Logger.getLogger(ClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClientImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

        return success;
    }
}


客户端接收文件线程
/**
 *
 * @author rikugun
 */
public class ClientThread implements Runnable {

    private Socket sock;
    private String file_name;
    private DataInputStream dis;
    private DataOutputStream fos, dos;
    private Properties prop;

    public ClientThread(Socket sock, String file_name, Properties prop) {
        this.sock = sock;
        this.file_name = file_name;
        this.prop = prop;
    }

    public void run() {
        try {
            dos = new DataOutputStream(sock.getOutputStream());
            dis = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
            //告知服务器需要获取的文件名
            dos.writeUTF(file_name);
            byte[] buf = new byte[Integer.parseInt(prop.getProperty("server.buf_size"))];
            if (dis.readBoolean()) {
                int read = 0;
                fos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(prop.getProperty("client.file_path") + File.separator + file_name)));
                while (true) {
                    read = dis.read(buf);
                    if (read == -1) {
                        break;
                    }
                    fos.write(buf,0,read);
                }
                fos.flush();
                fos.close();
                System.out.println("Success write the response to " + file_name);
            } else {
                System.out.println("Get file Failed! " + dis.readUTF());
            }
        } catch (IOException ex) {
            Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                dis.close();
                sock.close();
            } catch (IOException ex) {
                Logger.getLogger(ClientThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}


客户端测试类
/**
 *
 * @author rikugun
 */
public class ClientTest {

    static Properties prop = new Properties();
    static ServerImpl server;
    Client instance;

    public ClientTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        FileInputStream fis = new FileInputStream("conf.properties");
        prop.load(fis);
        System.out.println("Load prop success!");
        server =  new ServerImpl(prop);
//        server.startup();
        new Thread(server).start();
        if (server.isRunning()) {
            System.out.println("Server is running...");
        }else{
            System.out.println("Server start failed!");
        }
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
        server.stop();
    }

    @Before
    public void setUp() {
        instance = (Client) new ClientImpl(prop);
    }

    @After
    public void tearDown() {
    }

    /**
     * Test of getFiles method, of class Client.
     */
    @Test
    public void testGetFiles() {
        System.out.println("getFiles");
        String[] file_names = new String[]{"2.txt", "3.txt", "4.txt", "5.txt"};
        boolean expResult = true;
        boolean result = instance.getFiles(file_names);
        assertEquals(expResult, result);
    }

    /**
     * Test of getFile method, of class Client.
     */
    @Test
    public void testGetFile() {
        System.out.println("getFile");
        String file_name = "1.txt";
        boolean expResult = true;
        boolean result = instance.getFile(file_name);
        assertEquals(expResult, result);
    }
}
  • Code.gz (3.7 KB)
  • 下载次数: 52
  • 大小: 102.9 KB
4
0
分享到:
评论

相关推荐

    多线程文件下载CS结构转载

    本文将深入探讨一种客户端-服务器(Client-Server,简称CS)架构下的多线程文件下载实现。这种技术允许服务器同时处理多个客户端请求,提升整体系统性能。 【描述】:“转载的别人的,这个代码写的很清除,很实用,...

    QT中利用TCP协议实现了一个多线程的文件互传系统

    在QT框架下,利用TCP协议实现一个多线程的文件互传系统是一项常见的任务,它涉及到网络编程、多线程处理以及文件操作等多个方面。本文将深入探讨这些关键知识点。 首先,TCP(Transmission Control Protocol)是一...

    VC基于多线程的同步聊天,与文件传输

    在本文中,我们将深入探讨如何使用Microsoft Visual C++(简称VC)开发一个多线程的同步聊天及文件传输应用。这个项目结合了网络编程、多线程技术和文件操作,旨在实现客户端和服务端之间的实时通信和文件交换。 ...

    多线程传输文件 断点传输大文件

    总的来说,"多线程传输文件 断点传输大文件"这个项目通过多线程技术提高了文件传输的速度,通过互斥锁确保了数据一致性,通过共享内存实现了线程间的通信,而断点续传则提供了更好的用户体验。这些技术的结合运用,...

    多线程socket文件传输

    "多线程socket文件传输"是一个常见的应用场景,特别是在大数据交换、文件共享等需求中。本项目使用C语言实现了一个非阻塞的多线程socket文件传输程序,尽管可能存在一些问题,但对初学者来说,它能提供宝贵的实践...

    多线程下载demo,一分多个文件

    这个“多线程下载demo”项目就是专门为了实现这一目标,它允许我们将一个大的HTTP响应内容分割成多个小文件,然后通过多个线程并行下载这些片段,最后再将它们合并成原始文件。 首先,我们要理解什么是多线程。在...

    多线程传输文件

    本文将深入探讨“多线程传输文件”的概念、原理以及实际应用。 多线程指的是在一个程序中同时运行多个独立的执行线程。在文件传输场景下,多线程可以并行处理不同部分的文件,从而充分利用计算机的多核处理器资源,...

    多线程下载demo

    在多线程下载中,每个线程都会发送一个HTTP GET请求,指定文件的一个部分(如通过Range头来指定开始和结束字节)。 在实际应用中,还需要考虑一些其他因素,如错误处理(如网络中断、服务器错误等)、断点续传...

    多线程文件传输

    在多线程文件传输中,通常会有一个线程负责创建和维护SOCKET连接,而其他线程则负责读取本地文件并发送到远程,或者接收远程发送的文件。 文件`InitSock.h`可能包含了初始化套接字相关的函数声明,这些函数可能包括...

    多线程分别下载文件

    此外,文件存储也是多线程下载的一个关键部分。Android提供了File、FileOutputStream等类来处理本地文件操作。通常,下载的文件会被保存到外部存储(SD卡)或者内部存储的特定目录下,确保数据的持久化。 为了协调...

    基于MFC 的Socket类的多线程文件传输

    在文件传输过程中,多线程可以极大地提高效率,例如,一个线程负责接收文件,另一个线程负责写入磁盘,这样可以避免单线程操作时的阻塞,提高整体传输速度。在MFC中,我们可以使用CWinThread类来创建和管理线程。 ...

    C++ 实现多线程文件传输的设计与实现

    1. **客户端**:创建套接字,连接到服务器,发送文件大小信息,然后启动线程传输文件块。 2. **服务器**:监听客户端连接,接收文件大小信息,创建相应数量的线程接收并保存文件块。 3. **错误处理**:在网络环境...

    android文件多线程下载demo

    总之,“android文件多线程下载demo”涵盖了Android开发中的多线程编程和SQLite数据库应用两大关键知识点,对于初学者来说,这是一个很好的实践项目,可以帮助他们深入理解这两个重要概念,并将其应用于实际项目中。...

    java实现多线程文件传输

    5. **I/O流**:在Java中,`InputStream`和`OutputStream`是用于读写文件的基础类,多线程传输时,每个线程可以拥有自己的输入/输出流实例,分别处理文件的一部分。 6. **异常处理**:多线程环境下,需要确保每个...

    java多线程文件传输

    Java多线程文件传输是Java编程中一个重要的实践领域,特别是在大数据处理、网络通信和分布式系统中。在Java中,多线程可以提高程序的执行效率,尤其在处理并发任务时,如大文件的上传、下载和传输。下面将详细探讨...

    多线程socket文件传输_支持断点续传_收发消息_点对多点

    在多线程Socket文件传输中,通常会创建一个主线程负责管理连接和调度,而其他线程则分别处理文件的读写。这种方式允许并发处理多个文件传输,提高了系统的并行处理能力。对于断点续传功能,需要在客户端和服务器之间...

    基于WCF多线程的SOCKET文件传输服务

    总之,基于WCF的多线程SOCKET文件传输服务是一个复杂而实用的系统,它结合了WCF的易用性和SOCKET的灵活性,通过多线程实现了高效的文件并发传输。在设计和实现过程中,需要注意服务的可扩展性、安全性以及性能优化,...

    Android 多线程可断点续传上传文件至服务器Demo

    Android 多线程可断点续传上传文件至服务器Demo(Android端编辑器:Android Studio,服务器端编辑器:Eclipse,请注意手机默认下载目录必须要有t007.zip,服务器端必须有D:\temp\temp目录)

Global site tag (gtag.js) - Google Analytics