当前位置:网站首页>Handwritten a simple web server (B/S architecture)
Handwritten a simple web server (B/S architecture)
2022-07-31 22:49:00 【IT_WEH_coder】
涉及WebServer-related technologies
IO流、Socket网络编程、HTTP协议、文件、多线程(同时处理多个浏览器的请求)、List集合
1 webHow the application server works:
连接过程:WebThe connection established between the server and its browser,Determine whether the connection between the two is successful;If the user can find and open a virtual file socket,说明WebA connection is successfully established between the server and its browser.
请求过程:Web浏览器利用socketFiles make various requests to their servers.
Get the address of the requested resource
Make corresponding processing according to whether it is a static resource or a dynamic resource
响应过程:The request made during the request process is made by usingHTTP协议传输到Web服务器,Then perform task processing.
关闭连接:After the response process is complete,WebThe process by which a server disconnects from its browser.
2 代码展示
(1)Main类
package com.weh;
import com.weh.httpserver.MyHttpServer;
public class Main {
// 开启多线程
public static void main(String[] args) {
new Thread(new MyHttpServer()).start();
}
}
(2)MyHttpServer类
package com.weh.httpserver;
import com.weh.response.MyResponse;
import com.weh.request.MyRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/* * 1.通过Runnable接口的实现类,来开启线程 * 2.Create and start the server * 3.Implement the connection communication between the server and the client * */
public class MyHttpServer implements Runnable{
public static final int port = 8080; //服务器端口号
public static final String WEB_ROOT=System.getProperty("user.dir")+
File.separator+ "webapps"; //The current file directory path of the server
@Override
public void run() {
ServerSocket serverSocket=null;
Socket socket;
InputStream input=null;
OutputStream output=null;
try {
System.out.println("Web服务器已开启");
serverSocket = new ServerSocket(port); //Pass in the port number and create the server
} catch (Exception e) {
System.exit(0);
}
//The server communicates with the client browser
while(true){
try {
socket=serverSocket.accept();//请求
input=socket.getInputStream();//Get the information sent by the client
output=socket.getOutputStream();
MyRequest request=new MyRequest(input); //数据处理
request.parse();
MyResponse response=new MyResponse(output);
response.setMyRequest(request);
response.sendStaticResource();//发送
} catch (Exception e) {
e.printStackTrace();
continue;
}finally {
// 释放资源
release(input,output);
}
}
}
// 释放资源
public void release(InputStream inputStream,OutputStream outputStream){
try {
if(inputStream != null) {
inputStream.close();
}
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)MyRequest类
package com.weh.request;
import java.io.InputStream;
/* * 自定义MyRequest类 * 1.It mainly processes the information sent by the client and outputs it * 2.Get the name of the file to which the client switches * */
public class MyRequest {
private InputStream input;
private String uri;
public MyRequest(InputStream input){
this.input=input;
}
// 输出客户端发过来的信息
public void parse(){
StringBuffer request=new StringBuffer(2048);
int len;
byte[] buffer=new byte[2048];
try {
len=input.read(buffer);
} catch (Exception e) {
len=-1;
}
for(int j=0;j<len;j++){
request.append((char)buffer[j]);
}
System.out.print(request.toString());
parseUri(request.toString());
}
// Get the switched filename
public void parseUri(String srt){
int index1,index2;
index1=srt.indexOf(" ");
if(index1!=-1){
index2=srt.indexOf(" ",index1+1);
if(index2>index1){
setUri(srt.substring(index1+1,index2));
}
}
}
public void setUri(String uri) {
this.uri = uri;
}
public String getUri(){
return this.uri;
}
}
(4)MyResponse类
package com.weh.response;
import com.weh.httpserver.MyHttpServer;
import com.weh.request.MyRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/* * 自定义MyResponse类 * 1.向SocketThe result of writing the request to the browser to respond to the output stream * 2.Gets all files in the current directory and creates an array of file types * 3.Reading and forwarding of data * */
public class MyResponse {
private static final int BUFFER_SIZE=1024;
MyRequest request;
OutputStream output;
FileInputStream fis=null;
PrintWriter printWriter =null;
public MyResponse(OutputStream output){
this.output=output;
}
public void setMyRequest(MyRequest request){
this.request=request;
}
public void sendStaticResource()throws IOException{
byte[] bytes=new byte[BUFFER_SIZE];
try {
printWriter = new PrintWriter(output); //创建缓冲字符输出流
File file=new File(MyHttpServer.WEB_ROOT+request.getUri());
if(file.exists()){
//判断文件目录是否存在
//向SocketThe result of writing the request to the browser to respond to the output stream
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type:text/html;charset=UTF-8");
printWriter.println();
// 判断文件是否为普通文件
if(file.isFile()){
fis=new FileInputStream(file.getPath()); //创建文件字节输入流
fis.read(bytes); //read direct stream
printWriter.write(new String(bytes));
// Determines whether the file is a file directory
}else if(file.isDirectory()){
List<File> list= Arrays.asList(new File(file.getPath()).listFiles());//Gets all files in the current directory and creates an array of file types
for(File filename : list){
//数组遍历
if(filename.getName().indexOf(".htm")>0) {
//判断是否含有.htm的字符的文件
printWriter.write("<li>");
printWriter.write("<a style='text-decoration:blink;' href='" +
"./" + filename.getName() + "'>"
+ filename.getName() + "</a>");
printWriter.write("</li>");
}
}
}
// 若该文件不存在,则输出信息 File Not Found
}else{
printWriter.println("HTTP/1.1 404 File Not Found");
printWriter.println("Content-Type:text/html;charset=UTF-8");
printWriter.println("Content-Length:23");
printWriter.println();
printWriter.write("<h1>File Not Found</h1>");
}
printWriter.flush();//不返回任何值,Only used to refresh the stream
} catch (Exception e) {
e.printStackTrace();
}finally{
if(printWriter!=null){
printWriter.close();
}
if(output!=null){
output.close();
}
if(fis!=null){
fis.close();
}
}
}
}
3项目的结构设计

4 效果展示

边栏推荐
- A high-quality WordPress download site template theme developed abroad
- renderjs usage in uni-app
- How to identify fake reptiles?
- Douyin fetches video list based on keywords API
- Commonly used security penetration testing tools (penetration testing tools)
- 「SDOI2016」征途 题解
- TestCafeSummary
- -xms -xmx(information value)
- grep command written test questions
- HTC using official firmware as bottom bag made ROM brush card bag tutorial
猜你喜欢

VOT2021比赛简介

Memblaze released the first enterprise-grade SSD based on long-lasting particles. What is the new value behind it?

C程序设计-方法与实践(清华大学出版社)习题解析

Socket Review and I/0 Model

UOS统信系统 - WindTerm使用

嵌入式开发没有激情了,正常吗?

Flink_CDC construction and simple use

AI automatic code writing plugin Copilot (co-pilot)

Golang - from entry to abandonment

Implementation of a sequence table
随机推荐
iNeuOS industrial Internet operating system, equipment operation and maintenance business and "low-code" form development tools
无状态与有状态的区别
SQL注入 Less38(堆叠注入)
hboot and recovery, boot.img, system.img
SQL注入 Less42(POST型堆叠注入)
How to get useragent
NVIDIA has begun testing graphics products with AD106 and AD107 GPU cores
Niuke.com brush questions (1)
In Golang go-redis cluster mode, new connections are constantly created, and the problem of decreased efficiency is solved
VOT2021 game introduction
Interview assault 69: TCP reliable?Why is that?
Implementation of a sequence table
linux view redis version command (linux view mysql version number)
日常--Kali开启SSH(详细教程)
(26)Blender源码分析之顶层菜单的关于菜单
SQL注入 Less46(order by后的注入+rand()布尔盲注)
One thing to say, is outsourcing company worth it?
spark reports an error OutOfMemory "recommended collection"
Shell常用脚本:Nexus批量上传本地仓库增强版脚本(强烈推荐)
数据分析(一)——matplotlib