多线程Web服务器的设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
代码:
package实验三;
import java.io.IOException; //导入输入输出流的文件包中的子包--异常处理包
import .ServerSocket; //导入网络包中的子包--服务器端套接字包
import .Socket; //导入网络包中的子包—客户端套接字包
public class Webserver { // 定义Webserver类
// 主程序类中要求只能有一个公共类
// JAVA解释器要求公共类必须放在与它同名的文件中
public static final int HTTP_PORT = 5029; // 声明并初始化一个静态最终类整型常量,作为服务器端的端口
// 静态成员变量可直接引用而不用实例化(其他必须实例化)
// 最终类不能被继承,避免被修改
private ServerSocket serverSocket; // 声明一个私有的ServerSocket类的成员变量
public void startServer(int port) { // 声明构造一个共有的无返回值带参量输入的成员方法startServer
try { // 捕捉异常方法体
serverSocket = new ServerSocket(port); // 实例化建立服务器端监听套接字
System.out.println("Web Server startup on " + port); // 标准打印输出一行并换行
while (true) { // 循环体(布尔型常量)
Socket socket= serverSocket.accept(); // 等待客户端连接呼叫,建立连接套接字
new Processor(socket).start(); // 实例化并启动线程,直接调用run 方法
}
} catch (IOException e) { // 匹配异常
e.printStackTrace(); // 处理异常—在控制台上显示异常信息
}
}
public static void main(String[] argv) throws Exception { // 声明构造主函数体(带用户输
// 入参数),抛出所有异常,程序执行入口
Webserver server = new Webserver(); // 声明实例化Webserver类对象server
if (argv.length == 1) {
server.startServer(Integer.parseInt(argv[0]));// 数据类型强制转换为整型(默认
// java将键盘输入的数据看作字符串)
} else {
server.startServer(Webserver.HTTP_PORT);// 启动服务
}
}
}
package实验三;
import java.io.*; //导入输入输出流包,且是导入包中所有类
import java.io.BufferedReader; //字符缓冲输入流包导入
import java.io.File; //文件流包导入
import java.io.IOException; //输入输出流异常处理包导入
import java.io.InputStream; //字节输入流包导入
import java.io.PrintStream; //字节输出打印流包导入,它是 OutputStream的子类import .Socket; //网络功能包套接字子包导入
public class Processor extends Thread{ //声明线程子类Processor,他的超类是 thread private PrintStream out; //声明私有成员变量—out(输出流)
private InputStream input; //声明私有成员变量—input(输入流)
public static final String WEB_ROOT="F:\\Java工作台\\计算机网络\\bin\\实验三"; //声明并初始化静态最终类字符串常量---服务器提供文件存储位置
public Processor(Socket socket) { //声明构造成员方法---创建线程
try { //创建异常处理机制
input=socket.getInputStream(); //赋值表达式—从套接字获得客户端连接输入,返回字节输入流 inputstream对象并赋值给input
out=new PrintStream(socket.getOutputStream());//实例化输出流对象—输出到客户端
} catch (IOException e) { //捕捉匹配异常
e.printStackTrace(); //显示异常信息
}
}
public void run() { //创建run方法,它是对象的线程体(这里涉及子类对超类的方法覆盖)-----在线程被创建启动后,直接调用
try { //构造监视块,捕捉异常
String fileName=parse(input); // 调用方法parse解析客户端请求信息获取请求文件名
readFile(fileName); // 调用方法readFile打开,读取文件
} catch (IOException e) { //捕捉匹配异常
e.printStackTrace(); //显示异常信息
}
}
public String parse(InputStream input) throws IOException { //声明并构造方法parse解析客户端输入请求,并抛出可能引发的所有异常
BufferedReader in=new BufferedReader(new InputStreamReader(input)); //声明并实例化字符缓冲输入流对象—用于服务器缓冲输入
String inputContent=in.readLine();//声明成员变量,用于存储调用in的成员方法读入的客户端输入数据
if (inputContent==null||inputContent.length()==0) {
sendError(400,"Client invoke error");//如果变量值为空或零,输出客户端调用错误信息
return null; //并返回空值,关闭连接
}
String request[]=inputContent.split(" "); //声明字符串数组,存放成员变量inputstream中内容以空格为界分割后的数据信息
if(request.length !=3) { //判断字符串数组长度是否为3
sendError(400,"Client invoke error");//若不为3,输出错误信息
return null;
}
String method=request[0];//声明成员变量method并赋值第一个字符数组中内容
String fileName=request[1];
String httpVersion=request[2];
System.out.println("Method:"+method+",file name:" +fileName +", HTTP version:"+httpVersion); //显示输出信息
return fileName;
}
public void readFile(String fileName) throws IOException {//构造方法读取文件内容,若发生错误抛出所有异常,并将异常处理交给调用者
File file=new File(Processor.WEB_ROOT+fileName);//实例化文件对象并与实际文件建立关联
if (!file.exists()) { //判断文件是否存在
sendError(404,"File Not Found");//文件不存在则输出错误信息—是输出显示在客户端
return;
}
InputStream in=new FileInputStream(file);//创建文件输入流对象并打开源文件
byte content[]=new byte[(int) file.length()]; //实例化字节数组
in.read(content); //从输入流对象中读入数据到字节数组content中