- 浏览: 62278 次
- 性别:
- 来自: 北京
文章分类
最新评论
如何实现一个简单的HttpServer。一个基础的Web服务器使用两个重要的类:java.net.Socket和java.net.ServerSocket。
1. HTTP请求
一个HTTP请求包括三个组成部分:方法—统一资源标识符(URI)—协议/版本,请求的头部,主体内容
HTTP请求例子: POST /examples/default.jsp HTTP/1.1 Accept: text/plain; text/html Accept-Language: en-gb Connection: Keep-Alive Host: localhost User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) Content-Length: 33 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate lastName=Franks&firstName=Michael //方法—统一资源标识符(URI)—协议/版本出现在请求的第一行。 POST /examples/default.jsp HTTP/1.1 这里POST是请求方法,/examples/default.jsp是URI,而HTTP/1.1是协议/版本部分。 //请求的头部包含了关于客户端环境和请求的主体内容的有用信息。例如它可能包括浏览器设置的语言,主体内容的长度等等。每个头部通过一个回车换行符(CRLF)来分隔的。 //主体内容 lastName=Franks&firstName=Michael
2. HTTP响应
HTTP响应包括三个部分:方法—统一资源标识符(URI)—协议/版本,响应的头部,主体内容
HTTP响应的例子: HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Date: Mon, 5 Jan 2004 13:13:33 GMT Content-Type: text/html Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT Content-Length: 112 <html> <head> <title>HTTP Response Example</title> </head> <body> Welcome to Brainy Software </body> </html> //响应头部告诉你该协议使用HTTP 1.1,请求成功(200=成功),表示一切都运行良好。 //响应的主体内容是响应本身的HTML内容。头部和主体内容通过CRLF分隔开来。
3. Socket类
套接字是网络连接的一个端点。套接字使得一个应用可以从网络中读取和写入数据。放在两个不同计算机上的两个应用
可以通过连接发送和接受字节流。为了从你的应用发送一条信息到另一个应用,你需要知道另一个应用的IP地址和套接
字端口。在Java里边,套接字指的是java.net.Socket类。要创建一个套接字,你可以使用Socket类众多构造方法中
的一个。其中一个接收主机名称和端口号:
public Socket (java.lang.String host, int port)
在这里主机是指远程机器名称或者IP地址,端口是指远程应用的端口号。例如,要连接yahoo.com的80端口,你需要
构造以下的Socket对象:
new Socket ("yahoo.com", 80);
一旦你成功创建了一个Socket类的实例,你可以使用它来发送和接受字节流。要发送字节流,你首先必须调用Socket
类的getOutputStream方法来获取一个java.io.OutputStream对象。要发送文本到一个远程应用,你经常要从返回
的OutputStream对象中构造一个java.io.PrintWriter对象。要从连接的另一端接受字节流,你可以调用Socket类的
getInputStream方法用来返回一个java.io.InputStream对象。
Socket socket = new Socket("127.0.0.1", "8080"); OutputStream os = socket.getOutputStream(); boolean autoflush = true; PrintWriter out = new PrintWriter( socket.getOutputStream(), autoflush); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputstream() )); // send an HTTP request to the web server out.println("GET /index.jsp HTTP/1.1"); out.println("Host: localhost:8080"); out.println("Connection: Close"); out.println(); // read the response boolean loop = true; StringBuffer sb = new StringBuffer(8096); while (loop) { if ( in.ready() ) { int i=0; while (i!=-1) { i = in.read(); sb.append((char) i); } loop = false; } Thread.currentThread().sleep(50); } // display the response to the out console System.out.println(sb.toString()); socket.close();
4. ServerSocket类
Socket类代表一个客户端套接字,即任何时候你想连接到一个远程服务器应用的时候你构造的套接字,使用
java.net.ServerSocket类。服务器套接字的实现。
ServerSocket和Socket不同,服务器套接字的角色是等待来自客户端的连接请求。一旦服务器套接字获得一个连接请
求,它创建一个Socket实例来与客户端进行通信。
要创建一个服务器套接字,你需要使用ServerSocket类提供的构造方法。服务器套接字的另一个重要的属性是
backlog,这是服务器套接字开始拒绝传入的请求之前,传入的连接请求的最大队列长度。
public ServerSocket(int port, int backLog, InetAddress bindingAddress);
对于这个构造方法,绑定地址必须是java.net.InetAddress的一个实例。一种构造InetAddress对象的简单的方法是
调用它的静态方法getByName,传入一个包含主机名称的字符串,就像下面的代码一样。
InetAddress.getByName("127.0.0.1");
下面一行代码构造了一个监听的本地机器8080端口的ServerSocket,它的backlog为1。
new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1"));
5. HttpServer实现
实现简单HttpServer的3个类:
HttpServer: 启动ServerSocket开始监听Socket,并处理Request请求,响应Response
Request: 处理Request请求
Response: 返回内容
HttpServer类
import java.net.*; import java.io.*; /** WEB_ROOT is the directory where our HTML and other files reside. * For this package, WEB_ROOT is the "webroot" directory under the * working directory. * The working directory is the location in the file system * from where the java command was invoked. */ public class HttpServer { public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot"; // shutdown command private static final String SHUTDOWN_COMMAND = "/SHUTDOWN"; // the shutdown command received private boolean shutdown = false; public static void main(String[] args) { HttpServer server = new HttpServer(); server.await(); } public void await() { ServerSocket serverSocket = null; int port = 8080; try { serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1")); } catch (IOException e) { e.printStackTrace(); System.exit(1); } // Loop waiting for a request while (!shutdown) { Socket socket = null; InputStream input = null; OutputStream output = null; try { socket = serverSocket.accept(); input = socket.getInputStream(); output = socket.getOutputStream(); // create Request object and parse Request request = new Request(input); request.parse(); // create Response object Response response = new Response(output); response.setRequest(request); response.sendStaticResource(); // Close the socket socket.close(); //check if the previous URI is a shutdown command shutdown = request.getUri().equals(SHUTDOWN_COMMAND); } catch (Exception e) { e.printStackTrace (); continue; } } } }
Request类
import java.io.InputStream; import java.io.IOException; public class Request { private InputStream input; private String uri; public Request(InputStream input) { this.input = input; } public void parse() { // Read a set of characters from the socket StringBuffer request = new StringBuffer(2048); int i; byte[] buffer = new byte[2048]; try { i = input.read(buffer); } catch (IOException e) { e.printStackTrace(); i = -1; } for (int j=0; j<i; j++) { request.append((char) buffer[j]); } System.out.print(request.toString()); uri = parseUri(request.toString()); } private String parseUri(String requestString) { int index1, index2; index1 = requestString.indexOf(' '); if (index1 != -1) { index2 = requestString.indexOf(' ', index1 + 1); if (index2 > index1) return requestString.substring(index1 + 1, index2); } return null; } public String getUri() { return uri; } }
Response类
import java.io.*; /** HTTP Response = Status-Line * (( general-header | response-header | entity-header ) CRLF) * CRLF * [ message-body ] * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ public class Response { private static final int BUFFER_SIZE = 1024; Request request; OutputStream output; public Response(OutputStream output) { this.output = output; } public void setRequest(Request request) { this.request = request; } public void sendStaticResource() throws IOException { byte[] bytes = new byte[BUFFER_SIZE]; FileInputStream fis = null; try { File file = new File(HttpServer.WEB_ROOT, request.getUri()); if (file.exists()) { fis = new FileInputStream(file); int ch = fis.read(bytes, 0, BUFFER_SIZE); while (ch!=-1) { output.write(bytes, 0, ch); ch = fis.read(bytes, 0, BUFFER_SIZE); } } else { // file not found String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 23\r\n" + "\r\n" + "<h1>File Not Found</h1>"; output.write(errorMessage.getBytes()); } } catch (Exception e) { // thrown if cannot instantiate a File object System.out.println(e.toString() ); } finally { if (fis!=null) fis.close(); } } }
发表评论
-
MiniTomcat - How Tomcat Works 20: JMX-Based Management
2009-09-15 15:31 682MiniTomcat - How Tomcat Works 2 ... -
MiniTomcat - How Tomcat Works 19: Manager Servlet
2009-09-15 15:31 765MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 18: Deployer
2009-09-15 15:30 779MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 17: Tomcat Startup
2009-09-15 15:30 790MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 16: Shutdown Hook
2009-09-15 15:29 731MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 15: Digester
2009-09-15 15:29 613MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 14: Server and Service
2009-09-15 15:29 782MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 13: Host and Engine
2009-09-15 15:28 674MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 12: StandardContext
2009-09-15 15:28 783MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 11: StandardWrapper
2009-09-15 15:27 877MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 10: Security
2009-09-15 15:27 760MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 9: Session Management
2009-09-15 15:26 734MiniTomcat - How Tomcat Works 9 ... -
MiniTomcat - How Tomcat Works 8: Loader
2009-09-15 15:26 691MiniTomcat - How Tomcat Works 8 ... -
MiniTomcat - How Tomcat Works 7: Logger
2009-09-15 15:24 531MiniTomcat - How Tomcat Works 7 ... -
MiniTomcat - How Tomcat Works 6: Lifecycle
2009-09-15 15:12 706MiniTomcat - How Tomcat Works 6 ... -
MiniTomcat - How Tomcat Works 5: Container
2009-09-15 15:08 606container -
MiniTomcat - How Tomcat Works 4: Tomcat Default Connector
2009-09-15 15:07 608default connector -
MiniTomcat - How Tomcat Works 3: Connector
2009-09-15 15:06 560connector -
MiniTomcat - How Tomcat Works 2: Servlet Container
2009-09-15 14:05 821开发一个简单的Servlet容器 1. Servlet编程是 ...
相关推荐
web开发 how-tomcat-works
How Tomcat Works中文版
how-tomcat-works中文版.pdf
how tomcat works 源码,经过整理引入idea可以直接运行
How Tomcat Works【英文PDF+中文HTML+源码】 How Tomcat Works 主要是讲解Tomcat如何运行的一些核心资料。
本书讲述一般Java Web server以及Tomcat的运行原理,对JavaEE编程有极大的好处。 可惜只有前6章。
How Tomcat Works 中文版+例程源码; 源码在src目录下
java版五子棋源码HowTomcatWorks 《How Tomcat Works》 every chapter demo . Here's my ebook: Part of the UML diagram is as follows. 1.The default connector class diagram: 2.The class diagram of ...
How Tomcat Works Tomcat原理的书
Amazon 介紹: http://www.amazon.com/How-Linux-Works-Superuser-Should/dp/1593270356/ref=sr_1_1?ie=UTF8&s=books&qid=1269504842&sr=1-1
How Tomcat works(PDF),不可用于商业用途,如有版权问题,请联系删除!
tomcat的基本思想,学习完可以对理解spring的基本原理有大致了解,很值得学习
HowTomcatWorks 中文版+源码.rar HowTomcatWorks 中文版+源码.rar
how tomcat works中文版 + 英文版,深入解析了tomcat的实现机制
How Tomcat Works 全书共20章!
Java版水果管理系统源码HowTomcatWorks 《How Tomcat Works》 every chapter demo . Here's my ebook: Part of the UML diagram is as follows. 1.The default connector class diagram: 2.The class diagram of ...
How Tomcat Works》这本书的读书笔记,及主要内容感想。 作为一个世界范围广泛使用的强大框架,Tomcat必然有非常多的设计思想、设计模式,让我们学习。
how tomcat works 高清版 学习tomcat必备书籍 how tomcat works
HowTomcatWorks(书和源码)