什么是HTTP服务器?要理解这个概念,我们先要知道HTTP协议。HTTP协议(HypertextTransferProtocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。这就是你为什么在浏览器中看到的网页地址都是以“http://”开头的原因。
由于HTTP协议是基于请求/响应范式的(相当于客户端/服务器)。一个客户端与服务器建立连接后,发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
在WWW中,“客户端”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程:建立连接、发送请求信息、发送响应信息、关闭连接。
现在我们就来做一个简易的http服务器程序,更深刻地理解它们的工作方式。这里我们做两个类HttpServer.java和HttpSession.java,同时我们将所有的web资源放在E://www目录下:
HttpServer.java:
package com.wepull.http;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpServer {
public void startServer() {
ServerSocket ss = null;
try {
ss = new ServerSocket(80);
while (true) {
Socket s = ss.accept();
new HttpSession(s).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
HttpServer server = new HttpServer();
server.startServer();
}
}
HttpSession.java
package com.wepull.http;
import java.io.*;
import java.net.Socket;
import java.text.DateFormat;
import java.util.Date;
public class HttpSession extends Thread {
public static final String PATH_NAME = "E://www//";
private Socket s;
public HttpSession(Socket s) {
super();
this.s = s;
}
@Override
public void run() {
BufferedReader br = null;
OutputStream out = null;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = s.getOutputStream();
String line = "";
while ((line = br.readLine()) != null) {
if (line.equals("")) {
break;
}
System.out.println(line);
String[] cmds = line.split(" ");
// 处理客户端更重要的指令
if (cmds[0].equals("GET")) {
String fileName = cmds[1].substring(1);
if (fileName.equals("")) {
fileName = "index.htm";
}
doGet(out, PATH_NAME + fileName);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
br.close();
out.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void printOkResponse(OutputStream out, File file) {
PrintWriter pw = new PrintWriter(out);
pw.println("HTTP/1.1 200 OK");
pw.println("Server: Apache-Coyote/1.1");
pw.println("ETag: W//"6381-1144994988000/"");
pw.println("Last-Modified: Fri, 14 Apr 2006 06:09:48 GMT");
pw.println("Content-Type: text/plain");
pw.println("Content-Length: " + file.length());
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL);
pw.println(df.format(new Date()));
pw.println("Connection: keep-alive");
pw.println("");
pw.flush();
}
private void doGet(OutputStream out, String fileName) {
printOkResponse(out, new File(fileName));
FileInputStream fis;
try {
fis = new FileInputStream(fileName);
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
完成后,启动我们的服务器程序,客户端浏览器就可以通过我们的IP和80端口访问到我们提供的服务,获取他们想要的web资源啦。