我一直在尝试制作一个显示文件索引的Java服务器。我正在创建一个SocketServer并将其连接到端口。然后创建一个充当客户端的套接字,并创建一个连接到客户端套接字输出流的PrintWriter。如果我将页面硬编码到PrintWriter,一切都会正常,但是当我尝试逐行读取文件并将其发送到PrintWriter时,什么都不会显示。
package com.github.masonnoyce;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Date;
import java.io.File;
import java.nio.file.Files;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
public class AServer
{
public static void main (String[] args) throws Exception
{
AServer server = new AServer();
int portNumber = 8080;
//create server socket and say that it is running
final ServerSocket myServer = new ServerSocket(portNumber);
System.out.println("I have Connected To Port " + portNumber);
boolean running = true;
while(running)
{
//See if anyone connects
try(Socket client = myServer.accept())
{
server.sendPage(client);
}
catch(IOException e)
{
System.out.println("Something went wrong streaming the page");
System.exit(1);
}
}
try
{
myServer.close();
}
finally
{
System.out.println("Server Is now closed");
}
}
private void sendPage(Socket client) throws Exception
{
System.out.println("Page writter called");
PrintWriter printWriter = new PrintWriter(client.getOutputStream());//Make a writer for the output stream to the client
BufferedReader reader = new BufferedReader(new FileReader("path/to/index.html"));//grab a file and put it into the buffer
String line = reader.readLine();//line to go line by line from file
while(line != null)//repeat till the file is empty
{
printWriter.println(line);//print current line
printWriter.flush();// I have also tried putting this outside the while loop right before
printWriter.close()
line = reader.readLine();//read next line
}
reader.close();//close the reader
pageWriter.close();//Close the writer
//***********This section works if I replace the While loop With It**********//
// pageWriter.println("HTTP/1.1 200 OK");
// pageWriter.println("Content-Type: text/html");
// pageWriter.println("\r\n");
// pageWriter.println("<p> Hello world </p>");
// pageWriter.flush();//needed to actually send the data to the client
// pageWriter.close();//Close the writer
//************Above is the Hardcoding I was talking about****************************//
}
}
现在,我知道服务器应该在线程上运行,目前它永远无法从技术上退出,并且不需要某些导入。我现在不担心这一点。我只需要弄清楚为什么PrintWriter在浏览器中呈现html时不喜欢使用文件。我已经创建了一个调试PrintWriter,它可以写入文件以测试我是否具有正确的文件位置,并且可以使用该文件。
您可能会使用Web浏览器测试服务器,因此实际上应该发送包含包含在硬编码部分中的HTTP标头的有效HTTP请求。因此,在打印文件内容之前,应添加标题部分。
此外,您还需要收集有关文件大小的信息,并发送"Content-Length: " + file_size + "\r\n"
标头。
在完成阅读页面文件之前,关闭printWriter存在一个错误,您需要在循环之后将其关闭:
while(line != null)//repeat till the file is empty
{
printWriter.println(line);//print current line
printWriter.flush();// I have also tried putting this outside the while loop right before
printWriter.close() // BUG: no ";" and closing printWriter too early
line = reader.readLine();//read next line
}
因此,将文件发送到客户端的更新方法如下:
private void sendPage(Socket client) throws Exception {
System.out.println("Page writter called");
File index = new File("index.html");
PrintWriter printWriter = new PrintWriter(client.getOutputStream());// Make a writer for the output stream to
// the client
BufferedReader reader = new BufferedReader(new FileReader(index));// grab a file and put it into the buffer
// print HTTP headers
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type: text/html");
printWriter.println("Content-Length: " + index.length());
printWriter.println("\r\n");
String line = reader.readLine();// line to go line by line from file
while (line != null)// repeat till the file is read
{
printWriter.println(line);// print current line
line = reader.readLine();// read next line
}
reader.close();// close the reader
printWriter.close();
}