4

您好,我在 Java 中创建了一个多线程 HTTP 服务器,使用 Web 浏览器时无法获取内容。当我使用 telnet 客户端从网络服务器读取时,它工作正常,但是使用诸如 chrome 之类的浏览器什么都没有显示。我在下面发布了 3 张图片,显示通过 telnet 的连接工作正常,另外一张图片显示了通过 chrome 浏览器调用网络服务器时使用的wireshark 捕获:

http://localhost:4568

Telnet 连接到 Web 服务器 200

Telnet 连接到 Web 服务器 404

线鲨

这是我在下面发布的代码。我将代码更改为单线程以便于调试,MainWebServer 中称为“调试部分”的部分是线程类包含的部分。

主网络服务器:

package my.simple.webserver;

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

@SuppressWarnings("unused")
public class mainWebServer {

private static ServerSocket ser = null;
private static Socket cli = null;
private static String host = null;
private static int port;
/**
 * @param args
 */
public static void main(String[] args) {
    // Get parameters
    if(args.length < 2)
    {
        setHost("localhost"); 
        port = 4568;        
    }
    else
    {
        setHost(args[0]);
        port = Integer.parseInt(args[1]);
    }

    // initialize server
    try {
        // change to take in host
        ser = new ServerSocket(port);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    while(true)
    {
        try {
            setCli(ser.accept());
            //(new Thread(new HttpThread(cli))).start();

            // Debugging section
            DataInputStream sockIn = new     DataInputStream(cli.getInputStream());
            HttpRequest req = new HttpRequest(cli);
            int cnt = 0;
            byte[] buffer = new byte[1024];
            while((cnt = sockIn.read(buffer)) >= 0)
            {
                System.out.println("We are here");
                req.checkMethod(new String(buffer));
                resetBuffer(buffer, 256);   
            }
            // end debugging section

            // run thread for client socket
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    }
    public static String getHost() {
    return host;
    }
    public static void setHost(String host) {
    mainWebServer.host = host;
    }
    public static Socket getCli() {
    return cli;
    }
    public static void setCli(Socket cli) {
    mainWebServer.cli = cli;
    }

    // remove after debugging
    public static void resetBuffer(byte[] buffer2, int i) {
        // TODO Auto-generated method stub
        for(int x=0; x < i; x++)
        {
        buffer2[x] = 0;
        }
    }
}

HttpRequest 类:

package my.simple.webserver;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

public class HttpRequest {
    private String method = null;
    private String path = null;
    private FileInputStream fis = null;
    private OutputStream os = null;
    private Socket mycli;

    private static final String HTTP_OK_RESPONSE = "HTTP/1.1 200 OK\r\n";
    private static final String HTTP_FNF_RESPONSE = "HTTP/1.1 404 NOT FOUND\r\n";
    private static final String HTTP_DATE_RESPONSE = "Date: Mon, 04-Jan-99 13:14:15 GMT\r\n";
    private static final String HTTP_SERVER_RESPONSE = "Server: Challenger\r\n";
    private static final String HTTP_CONTENT_TYPE = "Content-Type: text/html\r\n";
    private String HTTP_Content_Length = "Content-length: ";

    public HttpRequest(Socket myCli) {
        // TODO Auto-generated constructor stub
        mycli = myCli;
    }

    void checkMethod(String buffer)
    {
        // get data and parse for method, location and protocol
        // use switch statement based on method given
        System.out.println("buffer = " + buffer);
        StringTokenizer tok = new StringTokenizer(buffer);

        try
        {
            method = tok.nextToken();
            path = tok.nextToken();
        }
        catch(NoSuchElementException nse)
        {
            System.out.println(nse.getMessage());
            method = "";
        }
        //System.out.println("method=" + method + " path=" + path);

        switch(method)
        {
            case "GET":
                //System.out.println("Get method called");
                getMethod();
                break;
            case "HEAD":
                System.out.println("Head method called");
                break;
            case "POST":
                System.out.println("Post method called");
                break;
            case "PUT":
                System.out.println("Put method called");
                break;
            case "DELETE":
                System.out.println("Delete method called");
                break;
            case "TRACE":
                System.out.println("Trace method called");
                break;
            case "OPTIONS":
                System.out.println("Options method called");
                break;
            case "CONNECT":
                System.out.println("Connect method called");
                break;
            default:
                break;
        }
    }

    private void getMethod()
    {   
        String file;
        File f = null;
        // check if file exists
        if(path.equalsIgnoreCase("/"))
        {
            //file = checkForIndex();
            file = "index.html";
        }
        else
            file = path;
        System.out.println("file = " + file);
        // open file
        try {
            file = "badfile.html";
            f = new File(file);
            os = mycli.getOutputStream();
            //check if file exists
            if(f.exists())
            {
                byte[] buffer = null;
                buffer = HTTP_OK_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_DATE_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_SERVER_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_CONTENT_TYPE.getBytes();
                os.write(buffer);

                long fileLen = f.length();
                HTTP_Content_Length = HTTP_Content_Length.concat(String.valueOf(fileLen));
                HTTP_Content_Length = HTTP_Content_Length.concat("\r\n");
                buffer = HTTP_Content_Length.getBytes();
                os.write(buffer);

                fis = new FileInputStream(file);

                int nread, result;
                // read file
                while((nread = fis.available()) > 0)
                {
                    buffer = new byte[nread];
                    result = fis.read(buffer);
                    if(result == -1) break;
                    os.write(buffer);
                }
                System.out.println("Left the loop!");
                mycli.close();
            }
            else
            {
                // deal with 404
                byte[] buffer = null;
                buffer = HTTP_FNF_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_DATE_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_SERVER_RESPONSE.getBytes();
                os.write(buffer);
                buffer = HTTP_CONTENT_TYPE.getBytes();
                os.write(buffer);

                f = new File("fnf.html");
                long fileLen = f.length();
                HTTP_Content_Length = HTTP_Content_Length.concat(String.valueOf(fileLen));
                HTTP_Content_Length = HTTP_Content_Length.concat("\r\n");
                buffer = HTTP_Content_Length.getBytes();
                os.write(buffer);

                fis = new FileInputStream(f);

                int nread, result;
                // read file
                while((nread = fis.available()) > 0)
                {
                    buffer = new byte[nread];
                    result = fis.read(buffer);
                    if(result == -1) break;
                    os.write(buffer);
                }
                System.out.println("Left the loop!");
                mycli.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // end thread   
    }
}

我正处于时间紧缩状态,我很感激任何帮助。

谢谢!

4

2 回答 2

2

因为在HTTP协议中发送header后,需要在request和response中都发送一个空行(\r\n)来表示header部分的结束,例如

HTTP/1.1 200 OK
Content-Type: text/html             
Content-Length: 21
\r\n(EMPTY LINE) <- you forgot this one
<b>Hello World :D</b>
于 2013-10-08T06:47:58.103 回答
0

完成标题后添加“\r\n”。喜欢:

HTTP_Content_Length = HTTP_Content_Length.concat("\r\n\r\n");
于 2013-10-08T06:55:35.990 回答