【问题标题】:Java TCP Simple Webserver Problems with response codes (homework)Java TCP Simple Webserver 响应代码问题(作业)
【发布时间】:2015-04-22 04:08:40
【问题描述】:

这是我们正在上的一门课程的作业,我需要一些帮助。

我遇到问题,例如,尝试请求一个不存在的文件,它会出现一个 404 文件未找到页面,但是当我查看 Safari 的网络工具时,我可以看到响应代码是200,OK,这是定义错误,应该是错误的代码。

但是为什么我看不到,我在发生错误时发送错误代码标题,但它仍然不起作用。有人可以指出我正确的方向,或者只是说问题是什么,我可以解决它:D?

主要:

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class WebServer {

    private static int PORT = 8888;
    private static String ROOT_DIR = "";

    public static void main(String[] args) {


        if (isCorrect(args) == true) {

            boolean isRunning = true;

            try {

            /* Creates a new server socket */
                ServerSocket serverSocket = new ServerSocket();

            /* Binds the port to the server */
                SocketAddress localBindPoint = new InetSocketAddress(PORT);

                serverSocket.bind(localBindPoint);

                System.out.println("==============================================" +
                        "\n| HTTP Web Server |" +
                        "\n===================" +
                        "\n| Configuration: " +
                        "\n| Directory: " +
                        "\n| " + ROOT_DIR +
                        "\n| Port: " +
                        "\n| " + PORT +
                        "\n| Usage: <directory> <port>" +
                        "\n| ctrl-c to exit" +
                        "\n==============================================");
            /* The server is running */
                while (isRunning) {

                    try {

                /* Accept connection by client */
                        Socket socket = serverSocket.accept();

                /* Each connected client gets a new thread */
                        new Thread(new RequestHandler(socket, ROOT_DIR)).start();

                    } catch (IOException e) {
                        System.err.println(e.getMessage());
                    }
                }
            } catch (IOException e) {
                System.err.println("Address already in use!" +
                        "\nClose running connection or choose other port");
            }
        } else
            usageMsg();
        System.exit(1);
    }

    public static boolean isDirectory(String path){
        File filePath = null;
        try{

            filePath = new File(path);
            /* False if file is not a directory */
            if (!filePath.isDirectory())
                return false;

        }
        catch (Exception e){
            System.err.println(e.getMessage());
        }
        /* Seems to be a file path */
        return true;
    }

    public static boolean isCorrect(String[] args){

        if (args.length != 2){
            usageMsg();
            return false;
        }

        try{
            ROOT_DIR = args[0].toString();
            PORT = Integer.parseInt(args[1]);
        }
        catch (NumberFormatException n){
            System.err.println(n.getMessage());
        }

        if (!isDirectory(ROOT_DIR)){
            usageMsg();
            return false;
        }

        return true;
    }

    public static void usageMsg(){
        System.err.println("Invalid arguments"+
                "\nUsage: java -jar Webserver.jar <directory> <port>");
    }
}

请求处理程序:

import java.io.*;
import java.net.Socket;
import java.util.StringTokenizer;

/**
 * Web Server Request Handler.
 * Created on 2015-02-16.
 */

public class RequestHandler implements Runnable {

    /*
    TODO ( ) Problem 1
    TODO ( ) Problem 2
    TODO ( ) Problem 3
    TODO (X) Index page for first page.
    TODO (X) Read and download images & other files
    TODO ( ) Fix header responses
    TODO ( ) Error responses
     */

    private String
            OK = "HTTP/1.0 200 OK",
            NOT_FOUND = "HTTP/1.0 404 Not Found",
            BAD_REQUEST = "HTTP/1.0 400 Bad Request",
            FORBIDDEN = "HTTP/1.0 403 Forbidden",
            SERVER_ERROR = "HTTP/1.0 500 Internal Server Error";

    private String ROOT_DIR;
    private Socket client;
    private PrintStream send;
    private DataInputStream fromClient;
    private DataOutputStream out;

    RequestHandler(Socket client, String ROOT_DIR) {
        this.client = client;
        this.ROOT_DIR = ROOT_DIR;

        try {
            send = new PrintStream(client.getOutputStream());
            fromClient = new DataInputStream(client.getInputStream());
            out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));


        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

    /* Reads the HTTP request and responds */
    public void run() {
        String request = null;
        String fileName = null;
        StringTokenizer tok = null;

        try {

            /* Read HTTP request from client */
            while ((request = fromClient.readLine()) != null) {

                System.out.println(request);
                tok = new StringTokenizer(request);

            /* Extracts the file path from the GET command */
                if (tok.hasMoreElements() && tok.nextToken().equals("GET")
                        && tok.hasMoreElements()) {

                    fileName = tok.nextToken();
                } else
                    throw new FileNotFoundException();

                /* */
                if (fileName.endsWith("/"))
                    fileName += "index.html";

                /* Illegal characters, prevent access to super directories */
                if (fileName.indexOf("..") >= 0 || fileName.indexOf('|') >= 0
                        || fileName.indexOf(':') >= 0 || fileName.indexOf('~') >= 0) {

                    error(FORBIDDEN, "Forbidden Access", fileName);
                }
                else

                if (new File(fileName).isDirectory()) {
                    fileName = fileName.replace('\\', '/');
                    send.close();
                    return;
                }

            /* File name is ROOT_DIR + file name */
                fileName = ROOT_DIR + fileName;

            /* Create file */
                File file = new File(fileName);

                if (file.isDirectory()) {
                    fileName = fileName + "index.html";
                }
            /* File does not exist */
                if (file.exists()){
            /* Determines the MIME type of the file */
                    String mimeType = getMimeType(file);

            /* Sends the file */
                    sendFile(file, mimeType, fileName);
                    client.close();
                }
                else
                    error(NOT_FOUND, "404 File Not Found", fileName);
            }

        }
        catch (FileNotFoundException e) {
            System.err.println(e.getMessage());
        }
        catch (IOException e){
            System.err.println(e.getMessage());
        }
    }

    /* Sends the requested file to the client */
    public void sendFile(File file, String fileType, String fileName) {
        try {
            // Buffer must not be to low, => fragments
            int length = (int) file.length();
            FileInputStream fileIn = new FileInputStream(fileName);
            byte[] bytes = new byte[length];

            /* Write until bytes is empty */
            while ((length = fileIn.read(bytes)) != -1 ){
                out.write(bytes, 0, length);
                out.flush();
                out.writeBytes(OK);
                out.writeBytes("Server: Jakobs Web Server v1.0");
                out.writeBytes("Content-Type: " + fileType + "\r\n");
                out.writeBytes("Content-Length: " + length + "\r\n");
                out.writeBytes("");
            }
            send.close();
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }

    /* Sends the header response to the client */
    public void sendHeaderResponse(String code, String fileType){
        try {
            out.writeBytes(code);
            out.writeBytes("Server: Jakobs Web Server v1.0");
            out.writeBytes("Content-Type: " + fileType + "\r\n");
            out.writeBytes("");
        }
        catch (IOException e){
            System.err.println(e.getMessage());
        }
    }

    /* Sends error response to the client */
    public void error(String code, String error, String fileName){
        System.err.println(error +
                "\nFile Requested: " + fileName);

        /* Sends the error code header */
        sendHeaderResponse(code, fileName);

        /* Sends the error message and cause to client */
        send.print("<html><head><title>" + error + "</title></head><body>");
        send.print("<h1>" + error + "</h1>\r\n");
        send.println("Location: /" + fileName + "/\r\n");
        send.println("Exception Cause: " + error + "\r\n");
        send.print("<a href=\"index.html\">Start Page</a>");
        send.print("</body>\"</html>");
        send.flush();
        send.close();
    }

    /* Finds out the MIME type of the requested file */
    public String getMimeType(File f) {
        String file = f.toString();
        String type = "";
        if (file.endsWith(".txt")) {
            type = "text/txt";
        } else if (file.endsWith(".html") || file.endsWith("htm")) {
            type = "text/html";
        } else if (file.endsWith(".jpg")) {
            type = "image/jpg";
        } else if (file.endsWith(".png")) {
            type = "image/png";
        } else if (file.endsWith(".jpeg")) {
            type = "image/jpeg";
        } else if (file.endsWith(".gif")) {
            type = "image/gif";
        } else if (file.endsWith(".pdf")) {
            type = "application/pdf";
        } else if (file.endsWith(".mp3")) {
            type = "audio/mpeg";
        } else if (file.endsWith(".class")){
            type = "application/octet-stream";
        } else if (file.endsWith(".mp4")){
            type = "video/mp4";
        }
        return type;
    }
}

【问题讨论】:

    标签: java http tcp webserver


    【解决方案1】:

    确保你写了例如HTTP/1.1 404 Not Found 给客户,而不仅仅是400

    其实没有,你的问题是你没有正确结束响应。浏览器不断接收数据并显示未收到响应代码。让我看看如何在您的代码中解决此问题。

    另外,您使用client.getOutputStream() 周围的两个包装流将数据发送到客户端(sendout)。不知道你为什么这样做。这看起来很奇怪。您应该只使用一个包装流。而且您永远不会关闭out,这可能是您的问题,这就是浏览器认为尚未完全收到响应的原因。尝试使用一个流并正确处理它。

    好的,您的代码已修复。

    import java.io.*;
    import java.net.Socket;
    import java.util.StringTokenizer;
    
    /**
     * Web Server Request Handler.
     * Created on 2015-02-16.
     */
    
    public class RequestHandler implements Runnable {
    
        /*
        TODO ( ) Problem 1
        TODO ( ) Problem 2
        TODO ( ) Problem 3
        TODO (X) Index page for first page.
        TODO (X) Read and download images & other files
        TODO ( ) Fix header responses
        TODO ( ) Error responses
         */
    
        private String
                OK = "HTTP/1.0 200 OK",
                NOT_FOUND = "HTTP/1.0 404 Not Found",
                BAD_REQUEST = "HTTP/1.0 400 Bad Request",
                FORBIDDEN = "HTTP/1.0 403 Forbidden",
                SERVER_ERROR = "HTTP/1.0 500 Internal Server Error";
    
        private String ROOT_DIR;
        private Socket client;
        private PrintStream send;
        private DataInputStream fromClient;
        // private DataOutputStream out;
    
        RequestHandler(Socket client, String ROOT_DIR) {
            this.client = client;
            this.ROOT_DIR = ROOT_DIR;
    
            try {
                send = new PrintStream(client.getOutputStream());
                fromClient = new DataInputStream(client.getInputStream());
                // out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
    
    
            } catch (IOException e) {
                System.err.println(e.getMessage());
            }
        }
    
        /* Reads the HTTP request and responds */
        public void run() {
            String request = null;
            String fileName = null;
            StringTokenizer tok = null;
    
            try {
    
                /* Read HTTP request from client */
                while ((request = fromClient.readLine()) != null) {
    
                    System.out.println(request);
                    tok = new StringTokenizer(request);
    
                /* Extracts the file path from the GET command */
                    if (tok.hasMoreElements() && tok.nextToken().equals("GET")
                            && tok.hasMoreElements()) {
    
                        fileName = tok.nextToken();
                    } else
                        throw new FileNotFoundException();
    
                    /* */
                    if (fileName.endsWith("/"))
                        fileName += "index.html";
    
                    /* Illegal characters, prevent access to super directories */
                    if (fileName.indexOf("..") >= 0 || fileName.indexOf('|') >= 0
                            || fileName.indexOf(':') >= 0 || fileName.indexOf('~') >= 0) {
    
                        error(FORBIDDEN, "Forbidden Access", fileName);
                    }
                    else
    
                    if (new File(fileName).isDirectory()) {
                        fileName = fileName.replace('\\', '/');
                        send.close();
                        return;
                    }
    
                /* File name is ROOT_DIR + file name */
                    fileName = ROOT_DIR + fileName;
    
                /* Create file */
                    File file = new File(fileName);
    
                    if (file.isDirectory()) {
                        fileName = fileName + "index.html";
                    }
                /* File does not exist */
                    if (file.exists()){
                /* Determines the MIME type of the file */
                        String mimeType = getMimeType(file);
    
                /* Sends the file */
                        sendFile(file, mimeType, fileName);
                        client.close();
                    }
                    else
                        error(NOT_FOUND, "404 File Not Found", fileName);
                }
    
            }
            catch (FileNotFoundException e) {
                System.err.println(e.getMessage());
            }
            catch (IOException e){
                System.err.println(e.getMessage());
            }
        }
    
        /* Sends the requested file to the client */
        public void sendFile(File file, String fileType, String fileName) {
            try {
                // Buffer must not be to low, => fragments
                int length = 0; // (int) file.length();
                FileInputStream fileIn = new FileInputStream(fileName);
                byte[] bytes = new byte[1024];
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
                /* Write until bytes is empty */
                while ((length = fileIn.read(bytes)) != -1 ){
                    bos.write(bytes, 0, length);
                    // send.write(bytes, 0, length);
                    // send.flush();
                }
                bos.flush();
                bos.close();
                byte[] data1 = bos.toByteArray();
    
                System.out.print(new String(data1));
                send.print(OK);
                send.print("");
                send.print("Server: Jakobs Web Server v1.0");
                send.print("Content-Type: " + fileType + "\r\n");
                send.print("Content-Length: " + data1.length + "\r\n");
                send.println("");
                send.write(data1, 0, data1.length);
                send.println("");
    
                send.flush();
                send.close();
    
                fileIn.close();
    
            } catch (IOException e) {
                System.err.println(e.getMessage());
            }
        }
    
        /* Sends the header response to the client */
        public void sendHeaderResponse(String code, String fileType){
            try {
                send.print(code);
                send.print("Server: Jakobs Web Server v1.0");
                send.print("Content-Type: " + fileType + "\r\n");
                send.print("");
                send.println();
            }
            catch (Exception e){
                System.err.println(e.getMessage());
            }
        }
    
        /* Sends error response to the client */
        public void error(String code, String error, String fileName){
            System.err.println(error +
                    "\nFile Requested: " + fileName);
    
            /* Sends the error code header */
            sendHeaderResponse(code, fileName);
    
            // send.println("ERROR");
    
            /* Sends the error message and cause to client */
    
            send.print("<html><head><title>" + error + "</title></head><body>");
            send.print("<h1>" + error + "</h1>\r\n");
            send.println("Location: /" + fileName + "/\r\n");
            send.println("Exception Cause: " + error + "\r\n");
            send.print("<a href=\"index.html\">Start Page</a>");
            send.print("</body></html>");
    
            send.flush();
            send.close();
        }
    
        /* Finds out the MIME type of the requested file */
        public String getMimeType(File f) {
            String file = f.toString();
            String type = "";
            if (file.endsWith(".txt")) {
                type = "text/txt";
            } else if (file.endsWith(".html") || file.endsWith("htm")) {
                type = "text/html";
            } else if (file.endsWith(".jpg")) {
                type = "image/jpg";
            } else if (file.endsWith(".png")) {
                type = "image/png";
            } else if (file.endsWith(".jpeg")) {
                type = "image/jpeg";
            } else if (file.endsWith(".gif")) {
                type = "image/gif";
            } else if (file.endsWith(".pdf")) {
                type = "application/pdf";
            } else if (file.endsWith(".mp3")) {
                type = "audio/mpeg";
            } else if (file.endsWith(".class")){
                type = "application/octet-stream";
            } else if (file.endsWith(".mp4")){
                type = "video/mp4";
            }
            return type;
        }
    }
    

    【讨论】:

    • 需要更多修复。
    • 显示html错误的东西?因为如果我得到一个错误,我会得到一个没有任何 html 格式的真正丑陋的页面。同样在主页中,您可以在底部看到 http 响应文本。还有什么? sv.tinypic.com/r/m8ia3a/8sv.tinypic.com/r/2djazio/8
    • 不,这是一个小问题 :) 现在 sendFile 也有同样的问题,浏览器一直在接收字节。你有很多错误。当你让我感兴趣时,我会尝试修复它们:)
    • 嗯,好吧。当我尝试获取 404 错误时,现在它会下载带有错误代码的纺织品,而不是在页面上显示它。一定是我的客人。
    • 好的,现在已经修复了。我做了几个小但重要的修复。与您的原始版本进行比较。
    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2023-03-06
    • 2018-02-13
    • 2016-03-19
    相关资源
    最近更新 更多