如何正确关闭输出/输入和FileOutput /输入流?

时间:2016-04-24 19:16:56

标签: java sockets

我在java中制作简单的Client-Server FileTransfer应用程序。

以下是此应用程序的概念:

  1. 客户端连接到服务器
  2. 服务器向Client显示菜单,如下所示

    • 2a)在服务器上复制文件
    • 2b)从中下载文件副本 服务器
    • 2c)退出
  3. 客户选择其中一个选项(客户端通过ObjectOutputStream发送消息,代码如下)。
  4. 问题是,当我选择其中一个选项时(例如选项#2a),我不能在之前完成时选择另一个选项。它说套接字很接近。

    有我的代码:

    客户端:

    public class Client {
    
        private Socket s = new Socket("localhost",3002);
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
        FileInputStream fis;
    
    
    
        public Client(String host, int port) throws IOException {
                //s = new Socket(host, port);
                try {
                    System.out.println("Hello!");
                    boolean finished = false;
                    Scanner sc = new Scanner(System.in);
                    while(!finished){
                        System.out.println("\n\n1.Make copy of file on server");
                        System.out.println("2.Restore copy");
                        System.out.println("3.Exit\n");
                        char c = sc.nextLine().charAt(0);
                        switch(c){
                        case '1':
                            this.sendMessage(1);
                            makeCopy();
                            oos.close();
                            break;
                        case '2':
                            this.sendMessage(2);
                            saveFile(s);
                            break;
                        case '3':
                            this.sendMessage(3);
                            finished=true;
                            System.exit(0);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }       
            }
    
            public static void main(String[] args) throws IOException {
                Client client = new Client("localhost",3002);
            }
    
            public void sendMessage(int message_id) throws IOException{
                oos.writeInt(message_id);
                oos.flush();
            }
    
            private void makeCopy() throws IOException {
                File file = new File("D:\\klient\\doKopii.bmp");
                File dest = new File("D:\\serwer\\kopiaPliku.bmp");
                boolean ifExists = dest.exists();
                if(ifExists && !file.isDirectory()){
                System.out.println("Copy is already on server.");
                }
                else{
                    fis = new FileInputStream(file);
                    byte[] buffer = new byte[4096];
                    while (fis.read(buffer) > 0) {
                        oos.write(buffer);
                    }
                }
                //fis.close();
                //oos.close();
            }
    
    
    
    
            private void saveFile(Socket clientSock) throws IOException {
                //DataInputStream dis = new DataInputStream(clientSock.getInputStream());
                FileOutputStream fos = new FileOutputStream("D:\\klient\\przywroconaKopia.bmp");
                File zSerwera = new File("D:\\serwer\\kopiaPliku.bmp");
                byte[] buffer = new byte[4096];
    
                int filesize = (int)zSerwera.length();
                int read = 0;
                int totalRead = 0;
                int remaining = filesize;
                while((read = ois.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
                    totalRead += read;
                    remaining -= read;
                    System.out.println("read " + totalRead + " bytes.");
                    fos.write(buffer, 0, read);
                }
    
                //fos.close();
                //ois.close();
            }
        }
    

    服务器端代码:

    public class Server extends Thread{
        private ServerSocket ss;
        Socket clientSock;
        ObjectInputStream ois;
        ObjectOutputStream oos;
        //DataOutputStream dos;
        FileInputStream fis;
        //DataInputStream dis;
        FileOutputStream fos;
        public Server(int port) {
            try {
                ss = new ServerSocket(port);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    
    
        public void run() {
                try {
                    while (true) {
                    clientSock = ss.accept();
                    oos = new ObjectOutputStream(clientSock.getOutputStream());
                    ois = new ObjectInputStream(clientSock.getInputStream());
                    serviceClient(clientSock);
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
        }
    
        public void serviceClient(Socket s) throws Exception{
            int message_id;
    
            try{
                message_id = ois.readInt();
                switch(message_id){
                case 1:
                    saveFile(s);
                    oos.flush();
                    break;
                case 2:
                    sendFile(s);
                    oos.flush();
                    break;
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    
        public void sendFile(Socket s) throws IOException {
            File file = new File("D:\\serwer\\kopiaPliku.bmp");
    
            fis = new FileInputStream(file);
            byte[] buffer = new byte[4096];
    
            while (fis.read(buffer) > 0) {
                oos.write(buffer);
            }
        }
    
    
        public void saveFile(Socket s) throws IOException{
            //dis = new DataInputStream(s.getInputStream());
            File copy = new File("D:\\serwer\\kopiaPliku.bmp");
            if(copy.exists() && !copy.isDirectory()){
    
            }
            else{
                fos = new FileOutputStream(copy);
                File zSerwera = new File("D:\\klient\\doKopii.bmp");
                byte[] buffer = new byte[4096];
    
                int filesize = (int)zSerwera.length();
                int read = 0;
                int totalRead = 0;
                int remaining = filesize;
                while((read = ois.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
                    totalRead += read;
                    remaining -= read;
                    System.out.println("read " + totalRead + " bytes.");
                    fos.write(buffer, 0, read);
                }
            }
        }
    
        public static void main(String[] args) {
            Server server = new Server(3002);
            server.start();
        }
    }
    

    确切异常:

    java.net.SocketException: Socket closed
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:116)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
        at java.io.ObjectOutputStream$BlockDataOutputStream.writeBlockHeader(ObjectOutputStream.java:1890)
        at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1875)
        at java.io.ObjectOutputStream$BlockDataOutputStream.flush(ObjectOutputStream.java:1822)
        at java.io.ObjectOutputStream.flush(ObjectOutputStream.java:719)
        at com.luki.classes.Client.sendMessage(Client.java:58)
        at com.luki.classes.Client.<init>(Client.java:33)
        at com.luki.classes.Client.main(Client.java:53)
    

    我必须在哪里关闭所有这些流以防止套接字关闭?

1 个答案:

答案 0 :(得分:0)

您在ObjectOutputStream的第一个案例陈述结束时关闭Client,原因无关紧要。删除该行,您将不会收到错误。