rikugun 发表于 2013-2-7 13:36:34

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

试一下JDK5的多线程编程,附件是代码,下载后改一下后缀名为.tgz

测试环境
OSX 10.5.6
JDK6
JUnit4.5

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

Test 图

http://www.agoit.com/upload/attachment/67236/2e3c864f-a954-33ec-a717-b6443b5a71b2.png


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;                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;            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);    }}
页: [1]
查看完整版本: 随手做一个多线程的 CS架构的 文件传输Demo