使用java的小型http服务器?

使用java的小型http服务器?,java,http,sockets,network-programming,Java,Http,Sockets,Network Programming,我使用java创建了以下测试服务器: import java.io.*; import java.net.*; class tcpServer{ public static void main(String args[]){ ServerSocket s = null; try{ s = new ServerSocket(7896); //right now the stream is open.

我使用java创建了以下测试服务器:

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

class tcpServer{
    public static void main(String args[]){
        ServerSocket s = null;
        try{
            s = new ServerSocket(7896);
            //right now the stream is open.
            while(true){
                Socket clientSocket = s.accept();
                Connection c = new Connection(clientSocket);
                //now the connection is established
            }
        }catch(IOException e){
            System.out.println("Unable to read: " + e.getMessage());
        }
    }
}
class Connection extends Thread{
    Socket clientSocket;
    BufferedReader din;
    OutputStreamWriter outWriter;

    public Connection(Socket clientSocket){
        try{
            this.clientSocket = clientSocket;
            din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), "ASCII"));
            outWriter = new OutputStreamWriter(clientSocket.getOutputStream());
            this.start();
        }catch(IOException e){
            System.out.println("Connection: " + e.getMessage());
        }   
    }
    public void run(){
        try{
        String line = null;
        while((line = din.readLine())!=null){
            System.out.println("Read" + line);
            if(line.length()==0)    
                break;
        }
        //here write the content type etc details:
        System.out.println("Someone connected: " + clientSocket);
        outWriter.write("HTTP/1.1 200 OK\r\n");
        outWriter.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
        outWriter.write("Expires: -1\r\n");
        outWriter.write("Cache-Control: private, max-age=0\r\n");
        outWriter.write("Content-type: text/html\r\n");
        outWriter.write("Server: vinit\r\n");
        outWriter.write("X-XSS-Protection: 1; mode=block\r\n");
        outWriter.write("<html><head><title>Hello</title></head><body>Hello world from my server</body></html>\r\n");
        }catch(EOFException e){
            System.out.println("EOF: " + e.getMessage());
        }
        catch(IOException e){
            System.out.println("IO at run: " + e.getMessage());
        }finally{
            try{
                            outWriter.close();  
                clientSocket.close();
            }catch(IOException e){
                System.out.println("Unable to close the socket");
            }
        }
    }
}
在我的浏览器上有一个空白的白色屏幕,源代码也是空白的。在谷歌浏览器中

谁能告诉我哪里错了。事实上,我对这件事还不熟悉。所以请纠正我

提前感谢

  • HTTP协议是基于ASCII的,除了依赖于内容类型头的主体之外。所以,没有UTF-8头文件
  • 标题和正文必须用空行分隔
  • 为什么要将Transfert编码设置为chuncked?你的身体不舒服

您几乎肯定不想在响应中使用
DataOutputStream
writeUTF
肯定不会做您想做的事情
DataOutputStream
是为二进制协议设计的,基本上,
writeUTF
写一个长度前缀为UTF-8的字符串,而HTTP只需要以CRLF结尾的ASCII文本行

您希望一次写出一行标题-因此在套接字输出流周围创建一个
OutputStreamWriter
,并写入:

writer.write("HTTP/1.1 200 OK\r\n");
writer.write("Date: Tue, 11 Jan 2011 13:09:20 GMT\r\n");
等等

您可能需要编写自己的
writeLine
方法来写出一行,包括结尾的CRLF(不要使用系统默认的行终止符),以使代码更干净

在页眉和正文之间添加一个空行,这样你的形状就合理了

编辑:还有两个更改:

首先,您应该阅读来自客户机的请求。例如,将
din
更改为
BufferedReader
,并按如下方式初始化它:

din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
                                               "ASCII"));
String line;
while ((line = din.readLine()) != null) {
    System.out.println("Read " + line);
    if (line.length() == 0) {
        break;
    }
}
然后,在开始写入输出之前,请按如下方式读取请求:

din = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
                                               "ASCII"));
String line;
while ((line = din.readLine()) != null) {
    System.out.println("Read " + line);
    if (line.length() == 0) {
        break;
    }
}
编辑:如注释中所述,这不适用于完整的HTTP服务器,因为它不能很好地处理二进制PUT/POST数据(它可能会将数据读入其缓冲区,这意味着您无法将其作为二进制数据从流中读取)。不过,对于测试应用程序来说,这很好

最后,您还应该关闭输出写入程序或至少刷新它,否则它可能正在缓冲数据


做出这些更改后,您的代码对我起作用。

我不确定您是否可以使用writeUTF,您可能需要使用
writeBytes
。另外,您需要用一个
'\n'

终止每一行。请检查此项,它已经为您完成了:


如果您对学习网络服务器(如Java中的HTTP服务器)的设计和开发感兴趣,您还可以看看以下repo:

这是一个Java的小型HTTP服务器,我是出于教育目的而启动的。不过,它还不应该用于生产或严重的用例中。我还在添加新功能。它目前提供多线程、静态文件处理、基本身份验证、日志记录和内存缓存

编辑

代码中的一个明显错误是\r\n响应头和HTML之间缺少。只需在最后一个标题中附加一个
\r\n
。此外,除非使用Chuncked编码,否则必须提供内容长度:

String out = "<html><head><title>Hello</title></head><body>Hello world from my server</body></html>\r\n";

outWriter.write("Content-Length: "+out.getBytes().length+"\r\n\r\n");
outWriter.write(out);
String out=“HelloHello world from my server\r\n”;
outWriter.write(“内容长度:“+out.getBytes().Length+”\r\n\r\n”);
写(出);

嘿,你能给我举一行例子吗?我对代码做了修改,但在谷歌chrome上仍然出现同样的错误。请检查此消息Hey abdullah我已经编辑了代码,现在正在运行,但我在google chrome上发现一个空白输出,页面源代码也为空白。您需要用\r\n终止每个标题。你根本不需要排队终止尸体。嘿,乔恩,我已经按照你说的那样做了,但还是得到了同样的结果error@codeomnitrix:在关闭套接字之前,您需要关闭写入程序-或者关闭,或者至少刷新写入程序。“您还需要阅读请求,至少是从Chrome上读到的——我已经在“包含该内容”中编辑了答案。”。但是请注意,问题中的代码在标题和正文之间仍然没有空行。你需要一个空行,例如,
outWriter.write(“\r\n”)
。嘿,jon,我已经做了很多,并且做了很好的响应,因为错误消失了,但仍然是空白的浏览器屏幕,没有任何源代码。第二,请您告诉我,在套接字之前关闭writer意味着什么。
BufferedReader
不适合在有可能包含二进制数据的消息实体时读取传入的HTTP请求(即使用PUT/POST上传图像的文件)。好的,谢谢,我将对此进行检查。谢谢你的回答。谢谢你的回答。问题解决了。但是地址或浏览器的意思是什么,即0:0:0:0:0:0:1
0:0:0:0:0:0:1
是使用IPv6时的
localhost
。好的,在头后再添加一个\n地址或浏览器后,这就起作用了。所以,感谢大家的支持嘿,但还有一件事让我觉得奇怪,浏览器地址是0:0:0:0:0:0:1??这是什么意思?如果你还不知道的话,这就指向你——Budi Kurniawan的《Tomcat是如何工作的》,Paul Deck是一个很好的起点。