簡體   English   中英

Java ObjectOutputStream的方法flush()

[英]Java ObjectOutputStream's Method flush()

我目前正在學習網絡,特別是客戶端服務器類。 我已經做了大量研究並實現了各種測試程序,但是我不知道為什么/何時需要使用flush()方法。

如果始終由輸入流讀取數據,怎么會在輸出流中錯誤地留下數據? 由客戶端服務器代碼規定。 我試圖通過省略flush()來測試基本的echo客戶服務器程序,但無法中斷。

通過從客戶端寫入兩次並僅讀取一次服務器答復來測試flush()時,所有發生的都是服務器答復中的積壓(我假設流的行為像隊列一樣?)。 然后,我采用了相同的代碼,在第二次寫入之前和之后添加了flush(),這沒有什么區別。 好像flush()並沒有真正清除流。

因此,有人可以解釋在哪種情況下需要客戶機/服務器流交互嗎?

服務器:

public class ServerApp
{
    private ServerSocket listener;
    private Socket clientCon;

    public ServerApp()
    {
        try
        {
            listener = new ServerSocket(1234, 10);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public void listen()
    {
        try
        {
            System.out.println("Server is listening!");
            clientCon = listener.accept();
            System.out.println("Server: Connection made with Client");

            processClient();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public void processClient()
    {
        try(ObjectOutputStream out = new ObjectOutputStream(clientCon.getOutputStream()); ObjectInputStream in = new ObjectInputStream(clientCon.getInputStream()))
        {
            String msg;
            while(!(msg = (String)in.readObject()).equalsIgnoreCase("Shutdown"))
            {
                out.writeObject("Server: " + msg);
                out.flush();
            }
            out.writeObject("Server is powering down...");

            out.close();
            in.close();
        } catch (IOException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }

    public static void main (String args[])
    {
        ServerApp sa = new ServerApp();
        sa.listen();
    }
}

客戶:

public class ClientApp
{
    private Socket serverCon;

    public ClientApp()
    {
        try
        {
            serverCon = new Socket("127.0.0.1", 1234);
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public void communicate()
    {
        try (ObjectOutputStream out = new ObjectOutputStream(serverCon.getOutputStream()); ObjectInputStream in = new ObjectInputStream(serverCon.getInputStream());
             BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
        {
            String response = null;
            do
            {
                System.out.println("Enter your message for server: ");
                out.writeObject(br.readLine());

                out.flush();
                out.writeObject("Flush not working");
                out.flush();

                response = (String) in.readObject();
                System.out.println(response);

                response = (String) in.readObject();
                System.out.println(response);
            } while (!response.equalsIgnoreCase("Server is powering down..."));
        } catch (IOException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String args[])
    {
        ClientApp ca = new ClientApp();
        ca.communicate();
    }
}

flush()方法用於清除可能正在使用的任何內部緩沖區。 例如,使用BufferedOutputStream將內容分塊寫入以提高性能(寫入每個字節時比較慢)。

根據用法,您可能不必調用flush()。 但是,假設您發送了一個小的String (轉換為byte[] ),它非常適合內部緩沖區。 緩沖區的內容只有在緩沖區已滿或調用flush()才會發送。

現在,假設您正在通過網絡進行編寫,並且希望另一端對您的小String做出回答。 由於它仍在緩沖區中,另一端將無法接收它,並且可能導致雙方永遠等待。

對象流是另一種野獸,令我如此失望的是,許多初學者正在使用它們。 在課堂上應該有一條警告,說“發送/接收對象可能比出現的對象更難”。

ObjectOutputStream代表的flush()調用到其內部BlockDataOutputStream具有3個緩沖器尺寸10245256為“BLOCKDATA”,報頭數據和字符分別。

使用new ObjectOutputStream(new BufferedOutputStream(clientCon.getOutputStream()))嘗試,無論是否使用flush(). ,您都會看到區別flush(). 它會導致底層緩沖輸出流的刷新。 沒有緩沖的流,就沒有要刷新的緩沖區,因此它什么也不做。

暫無
暫無

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

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