我已经使用 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");
}
}
}
}
现在我希望这个服务器响应我的浏览器。这就是为什么我给了 url: http://localhost:7896
结果我在服务器端收到:
ReadGET / HTTP/1.1
ReadHost: localhost:7896
ReadConnection: keep-alive
ReadCache-Control: max-age=0
ReadAccept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
ReadUser-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10
ReadAccept-Encoding: gzip,deflate,sdch
ReadAccept-Language: en-US,en;q=0.8
ReadAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
ReadCookie: test_cookie=test cookie
Read
Someone connected: Socket[addr=/0:0:0:0:0:0:0:1,port=36651,localport=7896]
我的浏览器出现空白屏幕,源代码也空白。在谷歌浏览器中。
所以任何人都可以告诉我我哪里错了。实际上我对这件事很陌生。所以请纠正我。
提前致谢
最佳答案
您几乎肯定不想在响应中使用 DataOutputStream
- 而 writeUTF
肯定不会执行您想要的操作。 DataOutputStream
基本上是为二进制协议(protocol)设计的 - 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;
}
}
编辑:如评论中所述,这不适用于完整的 HTTP 服务器,因为它不能很好地处理二进制 PUT/POST 数据(它可能会将数据读入其缓冲区,这意味着你不能那样做从流中将其作为二进制数据读取)。不过,对于测试应用程序来说没问题。
最后,您还应该关闭输出写入器或至少刷新它 - 否则它可能正在缓冲数据。
进行这些更改后,您的代码对我有用。
关于java - 使用java的小型http服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4655355/