【问题标题】:Read Data from a Java Socket从 Java 套接字读取数据
【发布时间】:2013-05-17 12:19:34
【问题描述】:

我有一个 Socket 在某个 x 端口上监听。

我可以从客户端应用程序将数据发送到套接字,但无法从服务器套接字获得任何响应。

  BufferedReader bis = new BufferedReader(new 
  InputStreamReader(clientSocket.getInputStream()));
  String inputLine;
  while ((inputLine = bis.readLine()) != null)
  {
      instr.append(inputLine);    
  }

..此代码部分从服务器读取数据。

但除非服务器上的 Socket 关闭,否则我无法从服务器读取任何内容。 服务器代码不受我控制,无法对其进行编辑。

如何从客户端代码中克服这个问题。

谢谢

【问题讨论】:

  • 听起来服务器没有刷新输出。如果是这种情况,据我所知,您无能为力。
  • 是的,但在这种情况下,我无法控制服务器.. 有什么建议吗?

标签: java sockets tcp


【解决方案1】:

看起来服务器可能没有发送换行符(这是 readLine() 正在寻找的)。尝试一些不依赖于此的东西。下面是一个使用缓冲方法的例子:

    Socket clientSocket = new Socket("www.google.com", 80);
    InputStream is = clientSocket.getInputStream();
    PrintWriter pw = new PrintWriter(clientSocket.getOutputStream());
    pw.println("GET / HTTP/1.0");
    pw.println();
    pw.flush();
    byte[] buffer = new byte[1024];
    int read;
    while((read = is.read(buffer)) != -1) {
        String output = new String(buffer, 0, read);
        System.out.print(output);
        System.out.flush();
    };
    clientSocket.close();

【讨论】:

    【解决方案2】:

    为了在客户端和服务器之间进行通信,需要明确定义协议。

    客户端代码阻塞,直到从服务器接收到一行,或者套接字关闭。你说你只有在套接字关闭后才会收到一些东西。因此,这可能意味着服务器不会发送以 EOL 字符结尾的文本行。 readLine() 方法因此阻塞,直到在流中找到这样的字符,或者套接字关闭。如果服务器不发送行,请不要使用 readLine()。使用适合定义协议的方法(我们不知道)。

    【讨论】:

    • 好的,我现在了解readLine(),但是有没有任何标准机制可以完全读取数据,而不管服务器协议是什么;)
    • 是的,从流中读取字节,直到返回-1,表示套接字已关闭。但是,如果您甚至不知道它是什么,那么接收它有什么意义呢?
    • 我理解定义明确的想法。我也有同样的问题。在我的服务器上,我使用 BufferedWriter 和 writeLine() ,然后刷新它。我仍然没有从缓冲输入流上的 readLine() 得到什么。使用与 readLine() 配对的 writeLine() 不会被认为是定义明确的吗?我尝试过两种方式发送通信,但没有收到任何信息。我已验证已建立连接。
    • @ydobonebi 发布您自己的问题,并附上诊断问题所需的相关代码。
    【解决方案3】:

    对我来说,这段代码很奇怪:

    bis.readLine()
    

    我记得,这将尝试读入缓冲区,直到找到'\n'。但是,如果从未发送过怎么办?

    我的丑陋版本打破了任何设计模式和其他建议,但始终有效:

    int bytesExpected = clientSocket.available(); //it is waiting here
    
    int[] buffer = new int[bytesExpected];
    
    int readCount = clientSocket.read(buffer);
    

    您还应该为错误和中断处理添加验证。 使用 web 服务结果,这对我有用(2-10MB 是最大结果,我已经发送了)

    【讨论】:

    • 根本不需要调用available(),而且不可靠。只需读入一个固定大小的缓冲区。 available() 的正确用法很少,这不是其中之一。
    • @EJP 我写的不正确,我告诉它正在工作,你的问题是什么?
    【解决方案4】:

    这是我的实现

     clientSocket = new Socket(config.serverAddress, config.portNumber);
     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    
      while (clientSocket.isConnected()) {
        data = in.readLine();
    
        if (data != null) {
            logger.debug("data: {}", data);
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 2014-06-07
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多