我正在编写一个简单的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参数。正如您现在所知道的,我对套接字编程不是很精通。怎么了 最佳答案
您需要侦听端口80:关于HTTPS的分配中没有任何内容。
请求主体不会在流的末尾终止,因为客户端仍然打开套接字以读取响应。
您需要从客户端读取Content-length标头,然后精确读取请求主体的这么多字节。
因此,您不能使用BufferedReader
解决此问题,因为您必须计算字节而不是字符。
将请求发送到服务器后,您真正需要做的就是将响应字节直接从服务器复制到客户端:而不是分配中的内容。
为了遵守作业中所说的内容,类似地,您必须从服务器读取Content-Length标头,并从服务器读取所有其他标头,空行以及确切的内容长度字节,然后将它们全部复制给客户。与仅复制字节相比,您可以看到这是浪费时间。
HTTP中的行终止符是\r\n
,而不是\n
。
作业不足:
指定不可行的BufferedReader
然后不一致地指定DataInputStream
从服务器读取
完全没有理由使用DataInputStream
:InputStream
就足够了
不涉及RFC 2616或其前身或后继
没有指定HTTP 1.0或1.1
不会多说“缓存网页”,仅在第2页提到过,此后再也没有。
学生应该抱怨。