Quantcast
Channel: HTML5
Viewing all articles
Browse latest Browse all 663

java socket 多线程网络传输多个文件

$
0
0

     由于需要研究了下用 java socket 传输文件,由于需要传输多个文件,因此,采用了多线程设计。客户端每个线程创建一个 socket 连接,每个 socket 连接负责传输一个文件,服务端的ServerSocket每次 accept 一个 socket 连接,创建一个线程用于接收客户端传来的文件。

1、服务端

    import java.io.BufferedInputStream;  
    import java.io.BufferedOutputStream;  
    import java.io.DataInputStream;  
    import java.io.DataOutputStream;  
    import java.io.FileOutputStream;  
    import java.net.ServerSocket;  
    import java.net.Socket;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  
      
    public class TransferServer {  
      
        private int defaultBindPort = Constants.DEFAULT_BIND_PORT;    //默认监听端口号为10000  
        private int tryBindTimes = 0;           //初始的绑定端口的次数设定为0  
          
        private ServerSocket serverSocket;      //服务套接字等待对方的连接和文件发送  
          
        private ExecutorService executorService;    //线程池  
        private final int POOL_SIZE = 4;            //单个CPU的线程池大小   
          
        /** 
         * 不带参数的构造器,选用默认的端口号 
         * @throws Exception 
         */  
        public TransferServer() throws Exception{  
            try {  
                this.bingToServerPort(defaultBindPort);  
                executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);  
                System.out.println("开辟线程数 : " + Runtime.getRuntime().availableProcessors() * POOL_SIZE);  
            } catch (Exception e) {  
                throw new Exception("绑定端口不成功!");  
            }  
        }  
          
        /** 
         * 带参数的构造器,选用用户指定的端口号 
         * @param port 
         * @throws Exception 
         */  
        public TransferServer(int port) throws Exception{  
            try {  
                this.bingToServerPort(port);  
                executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);  
            } catch (Exception e) {  
                throw new Exception("绑定端口不成功!");  
            }  
        }  
          
        private void bingToServerPort(int port) throws Exception{  
            try {  
                serverSocket = new ServerSocket(port);  
                System.out.println(port);  
                System.out.println("服务启动!");  
            } catch (Exception e) {  
                this.tryBindTimes = this.tryBindTimes + 1;  
                port = port + this.tryBindTimes;  
                if(this.tryBindTimes >= 20){  
                    throw new Exception("您已经尝试很多次了,但是仍无法绑定到指定的端口!请重新选择绑定的默认端口号");  
                }  
                //递归绑定端口  
                this.bingToServerPort(port);  
            }  
        }  
          
        public void service(){  
            Socket socket = null;  
            while (true) {  
                try {  
                    socket = serverSocket.accept();  
                    executorService.execute(new Handler(socket));  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
          
      
        class Handler implements Runnable{  
            private Socket socket;  
              
            public Handler(Socket socket){  
                this.socket = socket;  
            }  
      
            public void run() {  
                  
                System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());  
                  
                DataInputStream dis = null;  
                DataOutputStream dos = null;  
      
                int bufferSize = 8192;  
                byte[] buf = new byte[bufferSize];  
                  
                try {  
                    dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));  
                    String savePath = Constants.RECEIVE_FILE_PATH + dis.readUTF();  
                    long length = dis.readLong();  
                    dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(savePath)));  
                      
                    int read = 0;  
                    long passedlen = 0;  
                    while ((read = dis.read(buf)) != -1) {  
                        passedlen += read;  
                        dos.write(buf, 0, read);  
                        System.out.println("文件[" + savePath + "]已经接收: " + passedlen * 100L/ length + "%");  
                    }  
                    System.out.println("文件: " + savePath + "接收完成!");  
                      
                } catch (Exception e) {  
                    e.printStackTrace();  
                    System.out.println("接收文件失败!");  
                }finally{  
                    try {  
                        if(dos != null){  
                            dos.close();  
                        }  
                        if(dis != null){  
                            dis.close();  
                        }  
                        if(socket != null){  
                            socket.close();  
                        }  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }  
          
        public static void main(String[] args) throws Exception{  
            new TransferServer().service();  
        }  
    }  



2、客户端
    import java.io.BufferedInputStream;  
    import java.io.DataInputStream;  
    import java.io.DataOutputStream;  
    import java.io.File;  
    import java.io.FileInputStream;  
    import java.net.Socket;  
    import java.util.ArrayList;  
    import java.util.Random;  
    import java.util.Vector;  
    import java.util.concurrent.ExecutorService;  
    import java.util.concurrent.Executors;  
      
      
    public class TransferClient {  
      
        private static ArrayList<String> fileList = new ArrayList<String>();  
          
        private String sendFilePath = Constants.SEND_FILE_PATH;  
          
        /** 
         * 带参数的构造器,用户设定需要传送文件的文件夹 
         * @param filePath 
         */  
        public TransferClient(String filePath){  
            getFilePath(filePath);  
        }  
          
        /** 
         * 不带参数的构造器。使用默认的传送文件的文件夹 
         */  
        public TransferClient(){  
            getFilePath(sendFilePath);  
        }  
          
        public void service(){  
            ExecutorService executorService = Executors.newCachedThreadPool();  
            Vector<Integer> vector = getRandom(fileList.size());  
            for(Integer integer : vector){  
                String filePath = fileList.get(integer.intValue());  
                executorService.execute(sendFile(filePath));  
            }  
        }  
          
      
        private void getFilePath(String dirPath){  
            File dir = new File(dirPath);  
            File[] files = dir.listFiles();  
            if(files == null){  
                return;  
            }  
            for(int i = 0; i < files.length; i++){  
                if(files[i].isDirectory()){  
                    getFilePath(files[i].getAbsolutePath());  
                }  
                else {  
                    fileList.add(files[i].getAbsolutePath());  
                }  
            }  
        }  
          
        private Vector<Integer> getRandom(int size){  
            Vector<Integer> v = new Vector<Integer>();  
            Random r = new Random();  
            boolean b = true;  
            while(b){  
                int i = r.nextInt(size);  
                if(!v.contains(i))  
                    v.add(i);  
                if(v.size() == size)  
                    b = false;  
            }  
            return v;  
        }      
          
        private static Runnable sendFile(final String filePath){  
            return new Runnable(){  
                  
                private Socket socket = null;  
                private String ip ="localhost";  
                private int port = 10000;  
                  
                public void run() {  
                    System.out.println("开始发送文件:" + filePath);  
                    File file = new File(filePath);  
                    if(createConnection()){  
                        int bufferSize = 8192;  
                        byte[] buf = new byte[bufferSize];  
                        try {  
                            DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));  
                            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());  
                              
                            dos.writeUTF(file.getName());  
                            dos.flush();  
                            dos.writeLong(file.length());  
                            dos.flush();  
                              
                            int read = 0;  
                            int passedlen = 0;  
                            long length = file.length();    //获得要发送文件的长度  
                            while ((read = fis.read(buf)) != -1) {  
                                passedlen += read;  
                                System.out.println("已经完成文件 [" + file.getName() + "]百分比: " + passedlen * 100L/ length + "%");  
                                dos.write(buf, 0, read);  
                            }  
      
                           dos.flush();  
                           fis.close();  
                           dos.close();  
                           socket.close();  
                           System.out.println("文件 " + filePath + "传输完成!");  
                        } catch (Exception e) {  
                            e.printStackTrace();  
                        }  
                    }  
                }  
                  
                private boolean createConnection() {  
                    try {  
                        socket = new Socket(ip, port);  
                        System.out.println("连接服务器成功!");  
                        return true;  
                    } catch (Exception e) {  
                        System.out.println("连接服务器失败!");  
                        return false;  
                    }   
                }  
                  
            };  
        }  
          
        public static void main(String[] args){  
            new TransferClient().service();  
        }  
    }

3、常量类

    public interface Constants {  
      
        public final static String RECEIVE_FILE_PATH = "E:\\receive\\";  
          
        public final static String SEND_FILE_PATH = "E:\\send";  
          
        public final static int DEFAULT_BIND_PORT = 10000;  
    }  

    <pre name="code" id="best-content-1009763504" class="best-text mb-10" style="margin-top:0px; margin-bottom:10px; padding:0px; font-family:arial,'courier new',courier,宋体,monospace; white-space:pre-wrap; word-wrap:break-word; font-size:14px; line-height:24px; background-color:rgb(255,252,246)"></pre>  
    <pre></pre>  
    <pre></pre>  
    <pre></pre>  

  • java socket
  • 多线程
  • 图标图像: 

  • Technical Article

  • Viewing all articles
    Browse latest Browse all 663

    Trending Articles


    Vimeo 10.7.1 by Vimeo.com, Inc.


    UPDATE SC IDOL: TWO BECOME ONE


    KASAMBAHAY BILL IN THE HOUSE


    Girasoles para colorear


    Presence Quotes – Positive Quotes


    EASY COME, EASY GO


    Love with Heart Breaking Quotes


    Re:Mutton Pies (lleechef)


    Ka longiing longsem kaba skhem bad kaba khlain ka pynlong kein ia ka...


    Vimeo 10.7.0 by Vimeo.com, Inc.


    FORECLOSURE OF REAL ESTATE MORTGAGE


    FORTUITOUS EVENT


    Pokemon para colorear


    Sapos para colorear


    Smile Quotes


    Letting Go Quotes


    Love Song lyrics that marks your Heart


    RE: Mutton Pies (frankie241)


    Hato lada ym dei namar ka jingpyrshah jong U JJM Nichols Roy (Bah Joy) ngin...


    Long Distance Relationship Tagalog Love Quotes



    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>