我试图创建一个基本的符合 HTTP/1.1 的 Web 服务器,它支持具有持久连接的简单 GET 请求。我得到一个 SocketException: Connection Reset 错误发生在第 61 行(if (line==null || line.equals(""))。我正在通过运行它然后将我的 chrome 浏览器定向到 localhost 端口号来测试它。当我使用具有多个图像的页面对其进行测试时,似乎在发生异常之前只处理了一个请求,但我不确定出了什么问题,因为这是我第一次尝试任何类型的套接字编程。
这是删除 DataOutputStream 后我更新的代码:
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.StringTokenizer;
public class webserve
{
public static void main(String[] args) throws Exception
{
String rootPath = "~/Documents/MockWebServerDocument/";
int port = 10000;
if(rootPath.startsWith("~" + File.separator))
{
rootPath = System.getProperty("user.home") + rootPath.substring(1);
}
String requestLine="";
StringTokenizer tokens=null;
String line, command;
Date date = new Date();
String connectionStatus="";
//Create new server socket listening on specified port number
ServerSocket serverSocket = new ServerSocket(port);
while(true)
{
//Wait for a client to connect and make a request
Socket connectionSocket = serverSocket.accept();
System.out.println("Socket opened");
//Input stream from client socket
BufferedReader incomingFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//PrintWriter to send header to client socket
PrintWriter outgoingHeader = new PrintWriter(connectionSocket.getOutputStream(),true);
//OutputStream to send file data to client socket
ObjectOutputStream outgoingFile = new ObjectOutputStream(connectionSocket.getOutputStream());
//Date format for HTTP Header
SimpleDateFormat HTTPDateFormat = new SimpleDateFormat("EEE MMM d hh:mm:ss zzz yyyy");
//Create a HashMap to store the request header information
HashMap<String,String> requestHeader = new HashMap<String,String>();
while(connectionSocket.isConnected())
{
//requestHeader.clear();
while((line = incomingFromClient.readLine()) != null)
{
if(line.isEmpty())
{
break;
}
//If this is the first line of the request, i.e doesnt contain a colon
if(!(line.contains(":")))
{
requestLine = line;
requestHeader.put("Request", requestLine);
}
else
{
//Otherwise, find the colon in the line and create a key/value pair for the HashMap
int index = line.indexOf(':')+2;
String header = line.substring(0,index-1);
line = line.substring(index).trim();
requestHeader.put(header, line);
System.out.println(header + " " + line);
}
}
connectionStatus = (String)requestHeader.get("Connection:");
requestLine = (String)requestHeader.get("Request");
System.out.println("RequestLine: " + requestLine);
if(!requestLine.equals("")||!(requestLine.equals(null)))
{
tokens = new StringTokenizer(requestLine);
command = tokens.nextToken();
String filename = tokens.nextToken();
filename = cleanUpFilename(filename);
String fullFilepath = rootPath + filename;
System.out.println("Full FilePath: " + fullFilepath);
File file = new File(fullFilepath);
//Get the number of bytes in the file
int numOfBytes=(int)file.length();
//Open a file input stream using the full file pathname
FileInputStream inFile = new FileInputStream(fullFilepath);
//Create byte array to hold file contents
byte[] fileInBytes = new byte[numOfBytes];
inFile.read(fileInBytes,0,numOfBytes);
inFile.close();
//Write the header to the output stream
outgoingHeader.print("HTTP/1.1 200 OK\r\n");
outgoingHeader.print("Date: " + HTTPDateFormat.format(date)+"\r\n");
outgoingHeader.print("Server: BC-Server\r\n");
outgoingHeader.print("Last-Modified: " + HTTPDateFormat.format(file.lastModified())+"\r\n");
outgoingHeader.print("Connection: keep-alive\r\n");
outgoingHeader.print("Content-Length: " + numOfBytes);
outgoingHeader.print("\r\n\r\n");
//When the header has been printed, write the byte array containing the file
//to the output stream
outgoingFile.writeObject(fileInBytes);
if(!(connectionStatus.equals("keep-alive")))
{
System.out.println("Closing: " + connectionStatus);
outgoingHeader.close();
outgoingFile.close();
break;
}
else
continue;
}
}
}
}
public static String cleanUpFilename(String filename)
{
//If there is a "/" at the start of the filename, then remove it
if(filename.charAt(0) == '/')
{
filename = filename.substring(1);
}
//If we are given an absolute URI request, strip all characters
//before the third "/"
if(filename.startsWith("http://"));
{
try
{
URI httpAddress = new URI(filename);
//Get the path from the supplied absolute URI, that is remove
//all character before the third "/"
filename = httpAddress.getPath();
//Again, we may have to trim this modified address if there is an
//extra "/" at the start of the filename
if(filename.charAt(0) == '/')
{
filename = filename.substring(1);
}
}
catch (URISyntaxException e)
{
e.printStackTrace();
}
}
return filename;
}
}
这是我的错误跟踪:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:185)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:282)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:324)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:176)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:153)
at java.io.BufferedReader.readLine(BufferedReader.java:316)
at java.io.BufferedReader.readLine(BufferedReader.java:379)
at webserve.main(webserve.java:61)
任何帮助将不胜感激,因为我完全不知所措。