此版本较WebServer三添加或改进的功能
1.将服务端改为多线程方式,每个客户端连接后都启动一个线程进行处理
2.了解HTTP协议的基本交互规则和HTTP请求的内容格式
3.测试读取客户端发送过来的一行字符串
实现
1:在com.webserver.core下面新建一个类:ClientHandler,这是一个线程任务类,在线程上运行,用于处理某个客户端的HTTP交互
2:在ClientHandler中完成测试读取一行字符串的操作
3:在WebServer类中当一个客户端连接启动一个线程运行ClientHandler
第一步:下面新建一个类:ClientHandler
第二步:在ClientHandler中完成测试读取一行字符串的操作,并将webserver中获取字符串的操作注释或删除
第三步:在网页中输入http://localhost:8088/index.html 并查看是否在编译器中返回的值为GET /index.html HTTP/1.1 然后再次检验将index.html换成别的,例如 indextwo.html 是否返回的是GET /indextwo.html HTTP/1.1
演示截图
主要代码
//ClientHandler类中代码
package cn.webserver.core;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
/**
* @author Ryan
* 用于和指定客户端进行交互
* HTTP协议要求客户端与服务端的交互规则采用:一问一答方式
* 因此这里的处理流程分为三步
* 1.解析请求:读取客户端发送过来的请求内容(一问)
* 2.处理请求
* 3.响应客户端:发送一个响应给客户端(一答)
* 随后与客户端断开连接
*/
/*
runnable 接口
用于实现多线程
*/
public class ClientHandler implements Runnable{
private Socket socket; ///定义声明私有类socket
public ClientHandler (Socket socket){
this.socket = socket; //调用方法
}
public void run(){
//try…catch 异常处理机制
try{
//查看客户端发送的内容
//测试读取浏览器发送过来的每个字符(浏览器发送的都是单字节字符)
//通过socket获取输入流
InputStream inputstream = socket.getInputStream();
StringBuilder builder = new StringBuilder();
//做精确流读取,一个字节一个字节显示,不使用缓冲流
int i; //定义
//pre表示上次读取的内容,而cur表示本次读取的内容
//指显示一行,另外其中输出的时候显示的和你输入的要一样,GET /index.html HTTP/1.1 中间index.html,可以换成别的访问,但是输出中间要一样,为成功
char pre = 'a' , cur = 'a';
while((i = inputstream.read()) != -1){ //读取的字节数不为-1,就进行输出
//System.out.print((char)i); 将输出的结果转换成char(字符)类型
cur = (char)i;
builder.append(cur); //在cur后增加
if (pre == 13 && cur == 10){ // 在char类型中13代表回车符 10代表换行符
break; //满足if中条件,循环结束
}
pre = cur;
}
String line = builder.toString().trim();
System.out.println(line);
}catch(Exception exception){
exception.printStackTrace();
}finally { //finally一般是跟在try catch后面。finally中的语句无论何种情况下都会执行。
//一问一答后与客户端断开连接(HTTP1.0的交互要求)
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}