【问题标题】:Which IO classes are optimal for sending/receiving integer expressions through sockets in Java?哪些 IO 类最适合通过 Java 中的套接字发送/接收整数表达式?
【发布时间】:2020-09-24 19:52:38
【问题描述】:

我一直在学习 Java 中的客户端/服务器程序,并且对处理与服务器/客户端的读取和写入的许多不同方式感到不知所措。我的目标是从客户端一次发送一个 2 操作数整数表达式到服务器,服务器将评估它们并返回结果。我在下面列出了我遇到的 IO 选项。

输入示例

 - Scanner input = new Scanner(socket.getInputStream());
 - DataInputStream input = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
 - BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 - InputStream in = socket.getInputStream();
       DataInputStream input = new DataInputStream(in);
 - DataInputStream input =new DataInputStream(socket.getInputStream());
 - InputStream input = socket.getInputStream();

输出示例

 - PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
 - DataOutputStream output = new DataOutputStream(socket.getOutputStream());
 - OutputStream out = socket.getOutputStream();
       DataOutputStream output = new DataOutputStream(out);
 - PrintStream output = new PrintStream(socket.getOutputStream());
 - OutputStream output = socket.getOutputStream();
 - ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());

在所有这些方法中,哪一种最适合我的简单需求?另外,请让我知道其中一些方法是否过时,或者是否有一种更新的、传统的方法可用于这些天的基本套接字 IO。谢谢。

【问题讨论】:

  • 如果协议是基于文本的,我倾向于使用 BufferedReader 和 BuffereWriter 类,并且我尽可能使用基于文本的协议。我这样做主要是为了便于调试。

标签: java sockets network-programming serversocket java-io


【解决方案1】:

要知道,除了学习它之外,实际上并没有像您所说的那样使用原始 Sockets 的充分理由,而不是从构建 WebSocket 协议开始。从 WebSockets 入手会省去很多麻烦

首先,您需要决定是否需要/需要一个通信协议(如 http,它使用标头提供有关请求和响应的元信息)您说发送两个整数并接收处理后的结果。你有没有想过来回发送一些其他类型的数据?如果是这样,您将需要一个通信协议(例如,http 带有带有诸如内容类型等元信息的标头),以便接收者可以了解正在发送的内容。

您可能想在此处查看 DataFetcher 和 ServerSocketEx:(https://sourceforge.net/p/tus/code/HEAD/tree/tjacobs/io/) DataFetcher 是 InputStream 上消息的线程回调侦听器。 ServerSocketEx 负责使用 ServerSockets 的一些管道。

就您上面提到的类而言:Readers/Writers 用于读取和写入文本 - 不是二进制的。如果您要进行基于文本的通信,您应该选择一种文本格式(utf-8 是一个很好的默认选择)并确保发送方和接收方对此达成一致。

如果你正在做低效的读/写,你只需要流缓冲区,即逐行读取而不是仅仅吞噬字节或想要在通过套接字发送之前写几条消息。 p>

并且不要使用数据或对象流 - 这些是遗留的(数据流只能与 Java 后端通信)并且没有人真正使用它们。

最后一句话:注意 java.io.SocketException(我认为 ServerSocketEx 可以处理这个问题)。 SocketExceptions 是套接字通信的一个健康部分:这意味着套接字连接已关闭,并且它还释放了任何可能一直在等待更多信息进入的读取器线程。所以如果/当你得到这个时,不要惊慌.不要试图修复它。而是相应地处理它。

【讨论】:

  • 这里关于高度不相关的应用程序协议太多了,关于缓冲的部分是不正确的。当您一次读取一个字节时,您需要缓冲。使用BufferedReader.readLine() 读取行没有什么低效的,当然它按定义缓冲的。
  • @MarquisofLorne 我同意一次读取一个字节效率低下。但这是我试图画出的区别:如果您正在加载 JPEG 或 XML 文件,则需要在开始处理之前先加载整个流,以确保它是有效的。这就是我所说的高效阅读。当您使用 BufferedReader.readLine() 时,流中很可能有更多字符在您处理该行时尚未读取。
  • @MarquisofLorne 不仅如此,您还需要一个缓冲区来检查读取的数据是否有换行符,假设您一次不是读取 1 个字节,我们都认为这是低效的.我所做的不同之处在于,当您尽可能快地读取数据(没有中断)与检查数据时
猜你喜欢
  • 2016-12-08
  • 2012-02-12
  • 2021-08-16
  • 2020-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
相关资源
最近更新 更多