`
cwqcwq
  • 浏览: 74859 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

打造自己的web容器(1)

    博客分类:
  • j2ee
阅读更多
---- Socket入门

近日,读到一本好书---《How Tomcat Works》,该书详尽分析了tomcat的实现原理,解释了它的servlet容器的内部运行机制,读来非常有收获,特此撰文将读书过程中的一些心得付诸文字。

HTTP协议基础知识:

HTTP协议属于应用层协议,基于TCP,一个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 


类似于HTTP请求,一个HTTP响应也包括三个组成部分:方法—统一资源标识符(URI)—协议/版本、响应的头部、主体内容

HTTP响应示例:
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 5 Jan 2009 13:13:33 GMT
Content-Type: text/html
Last-Modified: Mon, 5 Jan 2009 13:13:12 GMT
Content-Length: 112

<html>
<head>
<title>HTTP Response Example</title>
</head>
<body>
Welcome !!
</body>
</html>


基于Socket的客户端-服务器:

客户端代码:

	public static void main(String[] args) throws InterruptedException {

		try {
			//创建一个流套接字并将其连接到指定 IP 地址的指定端口号
			Socket socket = new Socket("127.0.0.1", 8080);
			
			//模拟发送HTTP请求			
			OutputStream os = socket.getOutputStream();
			StringBuilder request = new StringBuilder();
			request.append("GET /index.jsp HTTP/1.1\n");
			request.append("Host: localhost:8080\n");
			request.append("Connection: Close\n");
			request.append("\n");
			os.write(request.toString().getBytes());
			os.flush();
			//os.close();//关闭 OutputStream 将关闭关联套接字
			
			//读取服务端响应
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			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;
				}
			}
			System.out.println(sb.toString());
			socket.close();
		}
		catch (UnknownHostException e) {
			// log error info
		}
		catch (IOException e) {
			// log error info
		}
	}



服务器端代码:

	public static void main(String[] args) {
		
		boolean shutdown = false;
		ServerSocket serverSocket = null;
		int port = 8080;
		try {
			//ServerSocket构造方法的参数说明:port - 本地 TCP 端口,backlog - 队列的最大长度,bindAddr - 要将服务器绑定到的 InetAddress
			serverSocket = new ServerSocket(port, 2, InetAddress.getByName("127.0.0.1"));
		}
		catch (IOException e) {
			// log error info
			System.exit(1);
		}
		// 等待请求
		while (!shutdown) {
			try {
				//侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞
				Socket socket = serverSocket.accept();
				
				//返回此套接字的输出流,用于向客户端写入返回结果
				OutputStream output = socket.getOutputStream();				
				
				//获取输入流,即客户端发起的HTTP请求
				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				StringBuffer sb = new StringBuffer(8096);
				boolean loop = true;
				while (loop) {
					if (in.ready()) {
						int i = 0;
						while (i != -1) {
							i = in.read();
							sb.append((char) i);
						}
						loop = false;
					}
				}
				// display the request to the out console
				System.out.println(sb.toString());
				output.write("Response: HTTP/1.1 200 OK ".getBytes());
			}
			catch (Exception e) {
				// log error info
				continue;
			}
		}
	}







分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics