簡體   English   中英

如何正確關閉Output / Input和FileOutput / Input流?

[英]How to close Output/Input and FileOutput/Input streams properly?

我正在用Java開發簡單的Client-Server FileTransfer應用程序。

這是此應用程序的概念:

  1. 客戶端連接到服務器
  2. 服務器向客戶端顯示菜單,如下所示

    • 2a)復制服務器上的文件
    • 2b)從以下位置下載文件副本
      服務器
    • 2c)退出
  3. 客戶端選擇這些選項之一(客戶端通過ObjectOutputStream發送消息,下面的代碼)。

問題是當我選擇一個選項(例如,選項#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)

我必須在哪里關閉所有這些流以防止套接字關閉?

沒有明顯的原因,您可以在Client中的第一個case語句的結尾關閉ObjectOutputStream 刪除該行,您將不會收到錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM