打造自己的web容器(1)

[b][color=red]---- Socket入门[/color][/b]

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

[color=red]HTTP协议基础知识:[/color]

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>


[color=red]基于Socket的客户端-服务器:[/color]

客户端代码:


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;
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值