java - Try/catch block 带有 while 语句,用于处理套接字数据,不会继续。没有明显的错误(我认为)

标签 java sockets http

这是我的主类 - Main.java。用于控制请求者,但为了完整性而添加。

import java.io.IOException;

import HtmlRequester.Requester;

public class Main {

public static void main(String[] args) {
    Requester rq = new Requester("www.google.co.za", 80);

    try {
        rq.htmlRequest();
    } catch (IOException e) {
        e.printStackTrace();
        System.err.println("Connection failed.");
        System.exit(-1);
    }

}
}

这是 requester.java,为简短起见进行了编辑。

package HtmlRequester;
import java.net.*;
import java.io.*;

public class Requester{
    Socket httpSocket = null;
    PrintWriter out = null;
    BufferedReader in = null;
    String server;
    int port;

public void setAttributes(String server, int port){
    this.server = server;
    this.port = port;
}

public String htmlRequest(String server, int port) throws IOException{
    try {
        httpSocket = new Socket(InetAddress.getByName(server), port);
        out = new PrintWriter(httpSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(
                httpSocket.getInputStream()));
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host: " + server);
        System.exit(-1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for "
                           + "the connection to: " + server + "on port " + port);
        System.exit(-1);
    }
    finally{
        System.out.println("Successful connection.");
    }

    out.println(compileRequestText());
    out.println("");

    String t;
    String ret = "";
    System.out.println("wait...");
    try {
        while((t = in.readLine()) != null)
        {
        ret.concat(t);
        System.out.println(t);
        }

        System.out.println("done");
    }
    catch(SocketException e)
    {
        System.err.println("Socket Exception :(");
    }
    System.out.println("Succesful data transfer.");

    out.close();
    in.close();
    httpSocket.close();
    return ret;
}

private String compileRequestText(){
    String ret = "GET / HTTP/1.1";

    return ret;
}
}

发生的情况是 Request.java 中的第二个 try-catch block ,该 block 包含:

while((t = in.readLine()) != null)

将执行,并成功显示服务器的响应。但是,显示响应后,循环将停止执行,代码不会前进到finally block 。该程序似乎在 while 循环之后没有继续。有人知道为什么吗?

即, System.out.println("完成"); 永远不会到达,不会引发异常或编译器错误。

最佳答案

服务器保持连接打开以允许客户端发送进一步的请求。客户端不应通过检测流已关闭来确定当前响应的结束,而是通过响应中发送的“Content-Length” header 来确定。

以下是如何重写循环以允许它提取该长度值:

  InputStream in = httpSocket.getInputStream();
  StringBuilder sb = new StringBuilder();
  boolean content = false;
  for (int i = 0; true; ++i) {
    if (content && i >= len)
      break;

    int ch = in.read();
    if(ch < 0)
      break;

    sb.append((char) ch);
    if (ch == '\n') {
      String s = sb.toString();
      if (!content && s.trim().isEmpty()) {
        content = true;
        i = 0;
      }
      if (len < 0)
        len = extractLength(s);

      System.out.print(s);
      sb = new StringBuilder();
    }
  }

  System.out.println(sb.toString());
  System.out.println("done");

这依赖于这两个辅助定义:

private static final String HEADER = "Content-Length: ";

private int extractLength(String s) {
  if (!s.startsWith(HEADER))
    return -1;
  return Integer.parseInt(s.substring(HEADER.length()).trim());
}

关于java - Try/catch block 带有 while 语句,用于处理套接字数据,不会继续。没有明显的错误(我认为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17776828/

相关文章:

java - JFrame 图像在帧调整大小时显示

http - 这是什么脚本语言? <%if $(http.request 方法 ='POST' ) >

python - 我如何要求此 Django View 使用 HTTPS?

java - 如何在 apache URIBuilder 中的端口后面添加尾部斜杠?

java - JApplet加载问题

java - Android套接字客户端 - 无法发送消息

apache-flex - 首选的套接字策略文件服务器实现?

python - 只需从github下载.git目录

Java - 两条线的碰撞检测

ios - 如何在特定接口(interface)上接收 UDP 广播数据包?