Java代理 - 无法从主机/套接字问题接收响应

时间:2016-02-21 22:53:15

标签: java sockets proxy bufferedreader

我正在编写一个简单的Java代理。总体架构是给我的(方法签名等),这是Main类的外观:

private static Socket clientSocket;
private static ServerSocket client;
private static int myPort;

public static void init(int port) throws IOException {
    client = new ServerSocket(port);
    clientSocket = client.accept();
}
public static void handle(Socket clientSocket) {
    try {
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        HttpRequest httpRequest = new HttpRequest(in);

        String hostname = httpRequest.getHost();
        //443 hardcoded from reading the http headers. 
        //Testing using isitchristmas.com
        Socket serverSocket = new Socket(hostname, 443);
        BufferedReader out = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
        HttpResponse httpResponse = new HttpResponse(out);
        serverSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
public static void main(String args[]) {
    try {
        myPort = Integer.parseInt(args[0]);
        try {
            System.out.println("Initializing socket...");
            init(myPort);
        } catch (IOException e) {
            System.out.println("[ERROR]: " + e.getMessage());
        }
        handle(clientSocket);
    } catch (Exception e) {
        System.out.println("[ERROR]: " + e.getMessage());
    }
}

但是,在HttpResponse类中读取时,控制台会挂起并且永远不会完成请求:

    public HttpResponse(BufferedReader fromServer) throws IOException {
    String line;
    String statusLine = "";
    // Never goes past here
    while ((line = fromServer.readLine()) != null) {
        if (line.isEmpty()) {
            break;
        }

        if (line.toLowerCase().contains("status")) {
            statusLine = line;
        }

        response.append(line);
    }

    if (!response.toString().isEmpty()) {
        getDataAndHeadersFromResponse(response.toString());
        System.out.println("\n\nHTTP Response:\n");
        System.out.println("Status Line: " + statusLine);
        System.out.println("Header Lines: " + headerLines + "\n\n");
        System.out.println("Data: " + data);
    }

}

我怀疑它与我如何创建套接字有关...不在close()上调用ServerSocket会发出一个已经在使用的地址:JVM_Bind异常。我似乎也没有得到serverSocket参数。正如你现在所知,我不太熟悉套接字编程。这有什么不对?

1 个答案:

答案 0 :(得分:1)

  • 您需要侦听端口80:关于HTTPS的任务中没有任何内容。
  • 请求正文不会在流结束时终止,因为客户端仍然打开套接字以读取响应。
  • 您需要从客户端读取Content-length标头,然后准确读取请求正文的多个字节。
  • 因此,您无法使用BufferedReader解决此问题,因为您必须计算字节数,而不是字符数。
  • 将请求发送到服务器之后,您真正需要做的就是将响应字节直接从服务器复制到客户端:它在分配中的含义。
  • 要坚持分配所说的内容,您同样必须从服务器读取Content-Length标头,以及所有其他标头和空白行,以及服务器响应的确切内容长度字节,以及将它们全部复制到客户端。与仅复制字节相比,您可以看到这是浪费时间。
  • HTTP中的行终止符为\r\n,而不是\n

作业缺乏:

  • 指定不可行的BufferedReader
  • 然后不一致地指定DataInputStream从服务器读取
  • 没有理由使用DataInputStreamInputStream就足够了
  • 不是指RFC 2616或其前身或后继者
  • 未指定HTTP 1.0或1.1
  • 没有详细说明缓存网页',这只是在第2页上提到过,之后再也没有提到过。

学生应该抱怨。