- 浏览: 65355 次
- 性别:
- 来自: 北京
文章分类
最新评论
如何实现一个简单的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 716MiniTomcat - How Tomcat Works 2 ... -
MiniTomcat - How Tomcat Works 19: Manager Servlet
2009-09-15 15:31 798MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 18: Deployer
2009-09-15 15:30 824MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 17: Tomcat Startup
2009-09-15 15:30 815MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 16: Shutdown Hook
2009-09-15 15:29 761MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 15: Digester
2009-09-15 15:29 640MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 14: Server and Service
2009-09-15 15:29 814MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 13: Host and Engine
2009-09-15 15:28 703MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 12: StandardContext
2009-09-15 15:28 808MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 11: StandardWrapper
2009-09-15 15:27 909MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 10: Security
2009-09-15 15:27 803MiniTomcat - How Tomcat Works 1 ... -
MiniTomcat - How Tomcat Works 9: Session Management
2009-09-15 15:26 766MiniTomcat - How Tomcat Works 9 ... -
MiniTomcat - How Tomcat Works 8: Loader
2009-09-15 15:26 728MiniTomcat - How Tomcat Works 8 ... -
MiniTomcat - How Tomcat Works 7: Logger
2009-09-15 15:24 567MiniTomcat - How Tomcat Works 7 ... -
MiniTomcat - How Tomcat Works 6: Lifecycle
2009-09-15 15:12 748MiniTomcat - How Tomcat Works 6 ... -
MiniTomcat - How Tomcat Works 5: Container
2009-09-15 15:08 642container -
MiniTomcat - How Tomcat Works 4: Tomcat Default Connector
2009-09-15 15:07 640default connector -
MiniTomcat - How Tomcat Works 3: Connector
2009-09-15 15:06 587connector -
MiniTomcat - How Tomcat Works 2: Servlet Container
2009-09-15 14:05 857开发一个简单的Servlet容器 1. Servlet编程是 ...
相关推荐
《Tomcat运行内幕-How Tomcat Works》这本书深入解析了Java Web服务器,特别是Apache Tomcat的工作机制,对于理解和优化Java EE应用的性能至关重要。虽然提供的章节有限,但我们仍能从中获取到许多关键知识点。 ...
"how-tomcat-works-master_howtomcatworks_"是一个关于Tomcat工作原理的源码分析项目,经过整理后可以在IntelliJ IDEA中直接运行,为开发者提供了一手的实践平台。 首先,我们要了解Tomcat的核心组件。Tomcat主要由...
《How Tomcat Works》中文版一书详细剖析了Tomcat服务器的内部工作机制。该书基于Tomcat 4.1.12和5.0.18两个版本,深入讲解了其servlet容器的架构和运作原理,尤其是代号为Catalina的核心组件。 Tomcat是一个开源的...
《How Tomcat Works》这本书深入浅出地介绍了Apache Tomcat这款广泛应用的Java Servlet容器的工作原理。Tomcat作为开源软件,是许多Web应用的基础,尤其在轻量级开发和测试环境中非常常见。以下是对Tomcat核心知识点...
《How Tomcat Works》是一份深入探讨Apache Tomcat工作原理的重要资源,包含了英文PDF文档、中文HTML翻译以及源代码,旨在帮助读者理解Tomcat服务器的内部运作机制。这份资料是IT从业者,特别是Java Web开发者、系统...
《How Tomcat Works》是一本深入探讨Apache Tomcat工作原理的书籍,中文版的提供使得国内开发者能够更方便地理解这一流行的开源Java Servlet容器。这本书不仅涵盖了Tomcat的基础知识,还详细解析了其内部机制,对于...
《How Tomcat Works》这本书是理解Apache Tomcat服务器工作原理的宝贵资源,它全面深入地讲解了这个流行的Java Servlet和JavaServer Pages(JSP)容器的内部机制。书中的20个章节涵盖了从基础概念到高级特性的广泛...
1. **Tomcat架构** Tomcat的架构主要包括以下几个关键组件:Catalina(Servlet容器)、Jasper(JSP引擎)、 Coyote(HTTP/1.1协议处理器)和Apr(Apache Portable Runtime)。 - **Catalina**:它是Tomcat的核心...
《How Tomcat Works》是一本深入探讨Apache Tomcat工作原理的中文版书籍,对于Java Web开发者来说,理解Tomcat的工作机制至关重要。Tomcat是Apache软件基金会的Jakarta项目中的一个核心部分,它是一个开源的、免费的...
《How Tomcat Works》这本书详细解释了Tomcat的工作原理,它不仅为新手提供了一个蓝图,帮助他们理解这个复杂的系统,也为有经验的开发者提供了深入学习的机会。 ### Tomcat的基本概念 Tomcat核心分为两个主要模块...
- 展示具体的类实现,如`HttpServer`、`Request`、`Response`等。 - **第3章:连接器(Connector)** - 详细介绍Connector的工作原理。 - 解析HTTP请求的过程。 - 如何创建和处理`HttpRequest`对象。 - **第4...
《HowTomcatWorks》是一本深入解析Apache Tomcat工作原理的书籍,中文版的发布使得更多的中国开发者能够理解和掌握这款广泛应用的开源Java Servlet容器的工作机制。Tomcat是Apache软件基金会Jakarta项目的一部分,它...
"HowTomcatWorks"项目,正如其名,旨在帮助开发者了解Tomcat的工作原理,通过源代码分享,使我们有机会深入探究这个强大的服务器内部机制。 1. **Tomcat架构概览** Tomcat的架构设计分为几个主要部分:Catalina...
《开发自己的Java Servlet容器的指南》是一本深入探讨Apache Tomcat工作原理的资源,而`javatomcat源码-HowTomcatWorks`这个压缩包正是提供了实现这些原理的源代码。Tomcat作为世界上最流行的Java Servlet容器之一,...
《How Tomcat Works》是一本深入解析Apache Tomcat服务器内部工作原理的重要参考资料,它提供了对Tomcat架构的全面理解,包括其设计、配置和优化。这本书的中文版和英文版都为读者提供了便利,无论你是母语为中文...
这个"中文版"暗示我们将探讨的内容是面向中文读者,可能是翻译自英文版的"How Tomcat Works",旨在帮助中文用户更好地理解Tomcat的内部运作机制。 **Tomcat基础知识:** Tomcat作为轻量级应用服务器,主要用于部署...
《How Tomcat Works》是一本深入探讨Apache Tomcat工作原理的书籍,包含了中英文两个版本。这本书对于理解Java Servlet和JavaServer Pages(JSP)容器的运作方式具有极高的价值,特别是对于那些想要深入理解Web应用...