gpt4 book ai didi

Java ObjectOutputStream 的方法flush()

转载 作者:行者123 更新时间:2023-11-30 03:11:39 27 4
gpt4 key购买 nike

我目前正在学习网络,特别是客户端服务器类(class)。我做了很多研究并实现了各种测试程序,但我无法弄清楚为什么/何时需要使用flush()方法。

总是由输入流读入,怎么可能会有数据误留在输出流中呢?正如客户端-服务器代码所规定的。我尝试通过省略flush()来测试我的基本echo客户端服务器程序,但我无法破坏它。

当通过从客户端写入两次并且只读取一次服务器的回复来测试flush()时,所有发生的情况都是服务器回复中的积压(我假设流的行为就像队列?)。然后我采用相同的代码并在第二次写入之前和之后添加了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 时,内容会以 block 的形式写入以提高性能(每个字节写入的速度会比较慢)。

根据使用情况,您可能永远不需要调用flush()。然而,假设您发送了一个小的String(转换为byte[])并且它非常适合内部缓冲区。在缓冲区已满或调用 flush() 之前,缓冲区的内容不会被发送。

现在,假设您正在通过网络进行写入,并且您希望对方对您的小String做出答复。由于它仍在缓冲区中,因此另一方不会收到它,这可能会导致双方永远等待。

对象流是另一个野兽,我对这么多初学者使用它们感到有点失望。类里面应该有一个警告,说“对象可能比它们看起来更难发送/接收”。

ObjectOutputStreamflush() 调用委托(delegate)给其内部 BlockDataOutputStream,该内部有 3 个大小为 1024 的缓冲区,5256 分别表示“blockdata”、 header 数据和字符。

关于Java ObjectOutputStream 的方法flush(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33496362/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com