🎈前言🎈
?作者:Leo? ?欢迎点赞👍收藏🌟留言、评论、私信必回哦? ?文章中涉及到的代码均已上传至GitHub? ?全文字数2567字,阅读时长10~20mins?
Verison1
项目目标:实现Tomcat的WebServer的核心功能 ????????????????? 将客户端发来的请求进行接收
项目代码
客户端(ClientHandler)
知识点:
- 调用Runnable接口重写run()方法,在线程启动后
执行run()方法中代码 - 利用Socket实现服务端客户端通信
- InputStream字节输入流,获取服务端接收的数据
- read()方法在读取完所有数据后返回-1表示读取完成
public class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) throws IOException {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
int d;
while ((d = in.read()) != -1) {
System.out.print((char) d);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器(Server)
public class BirdBootApplication {
private ServerSocket serverSocket;
public BirdBootApplication() {
try {
System.out.println("正在启动服务端...");
serverSocket = new ServerSocket(8088);
System.out.println("服务端启动完毕!");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
try {
System.out.println("等待客户端连接...");
Socket socket = serverSocket.accept();
System.out.println("一个客户端连接了!");
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
BirdBootApplication application = new BirdBootApplication();
application.start();
}
}
运行效果
客户端启动前 在浏览器中输入localhost:8088/index.html后(启动客户端)
Question:在客户端中若使用while(true)死循环读取请求数据会导致什么 Answer:在读取完请求头信息后线程没有关闭,导致死循环read()方法一直返回-1,需手动终止程序
Version2
项目目标:将请求数据(请求方式Method,抽象路径URI,协议版本Protocal)进行拆分并存入数组
项目代码
客户端(ClientHandler)
知识点
- 由Version1得知我们要获取的数据是GET /index.html HTTP/1.1,由此可采用寻找CRLF(回车换行符)来终止循环
- 用StringBuilder拼接InputStream中读取到的字符
- 将StringBuilder中的数据使用toString()方法转换为字符串,利用split方法进行剪切并存入数组
public class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream in = socket.getInputStream();
StringBuilder builder = new StringBuilder();
char pre='a',cur='a';
int d;
while((d = in.read())!=-1){
cur = (char)d;
if(pre==13&&cur==10){
break;
}
builder.append(cur);
pre = cur;
}
String line = builder.toString().trim();
System.out.println("请求行内容:"+line);
String method;
String uri;
String protocol;
String[] data = line.split("\\s");
method = data[0];
uri = data[1];
protocol = data[2];
System.out.println("method:"+method);
System.out.println("uri:"+uri);
System.out.println("protocol:"+protocol);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行效果
|