[英]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個緩沖器尺寸1024
, 5
和256
為“BLOCKDATA”,報頭數據和字符分別。
使用new ObjectOutputStream(new BufferedOutputStream(clientCon.getOutputStream()))
嘗試,無論是否使用flush().
,您都會看到區別flush().
它會導致底層緩沖輸出流的刷新。 沒有緩沖的流,就沒有要刷新的緩沖區,因此它什么也不做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.