持続的接続を使用した単純なGET要求をサポートする基本的なHTTP/1.1準拠のWebサーバーを作成しようとしました。61行目でSocketException:Connection Resetエラーが発生しています(if(line == null || line.equals( ""))。実行してから、Chromeブラウザーをローカルホストのポート番号に誘導してテストしています。複数の画像を含むページでテストすると、例外が発生する前に1つのリクエストしか処理されていないように見えますが、これはあらゆる種類のソケットプログラミングでの最初の試みであるため、何が問題なのかわかりません。
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)
私は完全に途方に暮れているので、どんな助けでも大歓迎です。