一个简单的HTTP服务器与Java /插座?一个简单的HTTP服务器与Java /插座?(A Sim

2019-05-16 15:19发布

我目前正在创建一个返回静态页面一个小的HTTP服务器<p>Hello!</p> ......我试图与Java插座:

  public static void main(String[] args) throws Exception {

        // création de la socket
        int port = 1989;
        ServerSocket serverSocket = new ServerSocket(port);
        System.err.println("Serveur lancé sur le port : " + port);

        // repeatedly wait for connections, and process
        while (true) {

            // on reste bloqué sur l'attente d'une demande client
            Socket clientSocket = serverSocket.accept();
            System.err.println("Nouveau client connecté");

            // on ouvre un flux de converation

           BufferedReader in = new BufferedReader(
                           new InputStreamReader(clientSocket.getInputStream())
                          ); 
            PrintWriter out = new PrintWriter(
                         new BufferedWriter(
                            new OutputStreamWriter(clientSocket.getOutputStream())), 
                         true);   

            // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur le flux d'écriture.
            // la donnée lue est donc retournée exactement au même client.
            String s;
            while ((s = in.readLine()) != null) {
                System.out.println(s);


       out.write("HTTP/1.0 200 OK\r\n");
       out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n");
       out.write("Server: Apache/0.8.4\r\n");
       out.write("Content-Type: text/html\r\n");
       out.write("Content-Length: 59\r\n");
       out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n");
       out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n");
       out.write("\r\n");
       out.write("<TITLE>Exemple</TITLE>");
       out.write("<P>Ceci est une page d'exemple.</P>");
  }

            // on ferme les flux.
            System.err.println("Connexion avec le client terminée");
            out.close();
            in.close();
            clientSocket.close();
        }
    }

这个代码不包含任何错误,我从这样的浏览器的响应:

GET / HTTP/1.1
Host: localhost:1989
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Comodo_Dragon/19.0.3.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

但我的问题是,我在浏览器中得到任何页面? 任何帮助吗?

PS:我已经看过这篇文章: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol ,(对不起的法语...)

Answer 1:

除了\r\n每个请求头行后,你有头之后发送一个空行。 例:

out.write("HTTP/1.0 200 OK\r\n");
// Header...
out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n");
out.write("\r\n"); // The content starts afters this empty line
out.write("<TITLE>Hello!</TITLE>");
// Content...

我纠正你的代码,以便它的工作原理(但它仍然是不完美的,你应该处理在一个单独的线程,例如每个请求java.util.concurrent.ThreadPoolExecutor ):

public static void main(String[] args) throws Exception {
    // création de la socket
    int port = 1989;
    ServerSocket serverSocket = new ServerSocket(port);
    System.err.println("Serveur lancé sur le port : " + port);

    // repeatedly wait for connections, and process
    while (true) {
        // on reste bloqué sur l'attente d'une demande client
        Socket clientSocket = serverSocket.accept();
        System.err.println("Nouveau client connecté");

        // on ouvre un flux de converation

        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

        // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur
        // le flux d'écriture.
        // la donnée lue est donc retournée exactement au même client.
        String s;
        while ((s = in.readLine()) != null) {
            System.out.println(s);
            if (s.isEmpty()) {
                break;
            }
        }

        out.write("HTTP/1.0 200 OK\r\n");
        out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n");
        out.write("Server: Apache/0.8.4\r\n");
        out.write("Content-Type: text/html\r\n");
        out.write("Content-Length: 59\r\n");
        out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n");
        out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n");
        out.write("\r\n");
        out.write("<TITLE>Exemple</TITLE>");
        out.write("<P>Ceci est une page d'exemple.</P>");

        // on ferme les flux.
        System.err.println("Connexion avec le client terminée");
        out.close();
        in.close();
        clientSocket.close();
    }
}


Answer 2:

这是一个答案,只有你的最后一个问题,并没有什么是在浏览器中可见,是因为你错误地计算字符数的原因。

它应该是57而不是59。

更好的方法是具有自动计算字符数,但我相信你的样本只是一个样品。



Answer 3:

您正在使用什么机器? 什么操作系统? 如果你正在运行的UNIX机器,那么的println将无法正常工作,因为它只能发送一个LF字符。 HTTP要求CR和LF其头。 尝试添加\ r您的字符串的结束,看看是否能工程。

哦,还有,你的:

  out.println("HTTP/1.0 200 OK"+
"Date: Fri, 31 Dec 1999 23:59:59 GMT"+
"Server: Apache/0.8.4"+
"Content-Type: text/html"+
"Content-Length: 59"+
"Expires: Sat, 01 Jan 2000 00:59:59 GMT"+
"Last-modified: Fri, 09 Aug 1996 14:21:40 GMT"+

它的打印单,长字符串。

改变那些一个println每串,或字符串添加\ r \ n。



Answer 4:

您需要正确的行分隔符( \r\n每行输出之间)。 这是不够的,只是将它们连接起来 - 你可以看到,如果你打印出来回应。



Answer 5:

温馨提醒:这不是一个HTTP服务器,作为标题建议。 它是写出一个特定硬编码HTTP响应(假设它是按照在其他答案建议固定)的插座。 即使你动态地改变返回的内容和内容长度的头,这还是不够的,必须符合HTTP协议。

正如我学到了艰辛的道路,而写JLHTTP ,还有很多比这更给HTTP。 这并不是说这是非常复杂的,但只是有要妥善处理了大量的额外的细节和要求。 你可以阅读的RFC(核心协议在RFC 7230中定义,或更早的RFC 2616),以更多地了解这个需要。

我也可以提供了JLHTTP源代码作为一个证据充分的最小兼容的实现HTTP服务器的基准 - 这是一个文件,目前3K〜线,几乎有一半是文档。 它的目标是成为微小的,但标准。 我觉得看代码可以为任何人想要学什么的HTTP服务器必须做有用的。 正如我所说的 - 不是很复杂,但有很多的小细节。

实际上,准确的说,JLHTTP不是尽可能最小的 - 它包括了一些有用的额外的功能,例如处理多形式的数据文件上传或支持HTTPS,其不通过HTTP协议本身必需的。 但是,你可以轻松地撕裂的部分出(或只是跳过它们),并在一个真正的Java最小HTTP服务器实现到达。



文章来源: A Simple Http Server with Java/Socket?