【问题标题】:Read all data from socket从套接字读取所有数据
【发布时间】:2013-07-10 23:13:26
【问题描述】:

我想在没有readline() 方法的情况下从客户端或服务器同步读取所有数据(如 c++ 中的readall())。
我不想使用类似下面的代码:

BufferedReader reader = new BufferedReader(new inputStreamReader(socket.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null)
     document.append(line + "\n");

我应该使用什么方法?

【问题讨论】:

  • 您反对使用您发布的代码的原因是什么?
  • 为什么要获取所有数据?使用 Sockets 的一个常见混淆是它支持接收消息的假设,如果你可以一次读取所有数据,你可以读取一个完整的“消息”。虽然这似乎可以在低负载下的 TCP 中工作,并且在“消息”之间存在时间,但 TCP 不支持这一点,并且这在负载下不能可靠地工作,尤其是在负载下。如果您需要基于消息的协议,您可以尝试 Java 7 中的 SCTP,或者按照预期的方式使用 TCP 作为流协议。
  • 诸如浏览器之类的东西永远不会在连接并等待响应时发送空值...我想一次同步读取所有标题和数据!
  • @Erfan13 请再试一次。我无法对那些胡言乱语做出头或尾。

标签: java sockets asynchronous


【解决方案1】:

你可以这样使用:

   public static String readToEnd(InputStream in) throws IOException {
      byte[] b = new byte[1024];
      int n;
      StringBuilder sb = new StringBuilder();
      while ((n = in.read(b)) >= 0) {
         sb.append(b);
      }
      return sb.toString();
   }

【讨论】:

    【解决方案2】:

    如果您知道传入数据的大小,您可以使用如下方法:

    public int read(char cbuf[], int off, int len) throws IOException;
    

    其中 cbuf 是目标缓冲区。

    否则,您将不得不读取行或读取字节。流不知道传入数据的大小。只能顺序读取直到到达结束(读取方法返回-1)

    参考这里streams doc

    这样的:

    public static String readAll(Socket socket) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null)
            sb.append(line).append("\n");
        return sb.toString();
    }
    

    【讨论】:

    • 我给你举了一个例子,因为还有一件更重要的事情需要注意:你应该使用 StringBuilder 而不是连接字符串。
    • +1 注意:这会读取所有字符,如果多字节字符不完整,会保存在缓冲区中,稍后会出现。
    • @Tala,在过时的 Java 优化技巧以及 Java 城市神话中,使用 StringBuilder 进行常规连接已过时。
    猜你喜欢
    • 2012-06-17
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2014-06-07
    • 2010-10-30
    • 2016-02-20
    相关资源
    最近更新 更多