主程序:
package com.xuyu;
import java.net.ServerSocket;
import java.net.Socket;
public class httpServer implements Runnable{
private static Boolean isRun = true;
private static Boolean isPush = true;
public static String resourcePath = "";
//监听端口
private int port ;
public httpServer(int port){
this.port = port;
}
@Override
public void run() {
//线程的主程序
//声明serverSocket对象
ServerSocket serverSocket = null;
try {
//创建ServerSocket对象
serverSocket = new ServerSocket(port);
//开始监听
System.out.println("开始监听...");
while(httpServer.this.isRun) {
//socket里面有双向管道,输入输出流
Socket socket = serverSocket.accept(); //阻塞状态,等待访问
System.out.println("接受到请求...");
//将socket交给RequestExecute处理
RequestExecute re = new RequestExecute(socket);
//创建线程处理请求
re.start();
}
//运行到这里程序结束
serverSocket.close();
serverSocket=null;
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("port"+port+"listen fail..."+e.getMessage());
}
}
public static void main(String[] args) {
httpServer httpServer = new httpServer(8088);
new Thread(httpServer).start();
}
}
多线程处理请求:
package com.xuyu;
import java.io.*;
import java.net.Socket;
//成员变量不用初始化,具部变量要初始化
//请求处理线程类
public class RequestExecute extends Thread{
//将Socket定义为成员变量,利用构造方法初始化
private Socket socket;
public RequestExecute(Socket socket){
this.socket=socket;
}
@Override
public void run(){
//从Socket中取出输入流,然后从输入流中取出数据
InputStream in = null;//将字节输入流转换为缓冲字符输入流
InputStreamReader reader = null;//转换流
BufferedReader bufferedReader = null;//字符缓冲流
//声明输出流,输出流是指向客户端的
OutputStream out = null;
PrintWriter pw = null; //包裹成字符输出流
try {
//从Socket中获取字节输出流
out = socket.getOutputStream();
//将字节输出流包装成字符流
pw = new PrintWriter(out);
//从Socket中获取字节输入流
in = socket.getInputStream();
//转换和包装
reader = new InputStreamReader(in);
bufferedReader = new BufferedReader(reader);
//循环的从字符流中获取字符
String line = null;
int lineNum =1;
//存储请求路劲
String reqPath = "";
String host = "";
//每次从中读取一行
while((line = bufferedReader.readLine())!=null){
System.out.println(line);
//解析请求行
if(lineNum == 1){
//使用空格分割字符串
String[] infos = line.split("");
if(infos!=null || infos.length>2){
reqPath = infos[1];//请求路径
}else {
throw new RuntimeException("请求行解析失败:"+line);
}
}else{
//解析其他行,取出Host的内容
String[] infos = line.split(": ");
if(infos!=null || infos.length==2){
if(infos[0].equals("Host")) {
host = infos[1];//取出host
}
}
}
lineNum++;
//读取到空行就结束,因为HTTP请求是长连接,无法读取到文件的末尾
if(line.equals("")) {
break;
}
}
//输出请求信息
System.out.println(host + reqPath);
//根据请求响应客户端 /直接返回欢迎页面 /index.html返回文件内容
if(reqPath.equals("/")){
pw.write("HTTP/1.1 200 OK \r\n"); //输出响应行
pw.write("Content-Type: text/html;charset = utf-8");
pw.println();//输出空行 表示响应头结束,开始响应内容
pw.write("<h2>Welcome search this</h2>");
pw.flush();
}else {
//查找对应的资源 /index.html
String ext = reqPath.substring(reqPath.lastIndexOf(".")+1); //取出后缀不包括.
reqPath = reqPath.substring(1); //去掉前面的/
//判断是在根目录下还是在其他的子目录下
if(reqPath.contains("/")){ //子目录
//判断文件是否存在
File file = new File(httpServer.resourcePath + reqPath); //C:/xuyu/app/resource.jpg
if(file.exists() &&file.isFile()){
response200(out,file.getAbsolutePath(),ext);
}else {
response404(out);
}
}else{ //根目录
//判断这个资源是否存在
//获取根目录下的所有的文件的名称
File root = new File(httpServer.resourcePath);
if(root.isDirectory()){
File[] list = root.listFiles();
boolean isExist = false; //标记访问的资源是否存在
for(File file : list){
if(file.isFile() && file.getName().equals(reqPath)){
//文件存在
isExist = true;
break;
}
}
if(isExist){//文件存在
response200(out,httpServer.resourcePath+reqPath,ext);
}else { //文件不存在
response404(out);
}
}else{
throw new RuntimeException("静态资源目录不存在:"+httpServer.resourcePath);
}
}
}
}catch (IOException e){
e.printStackTrace();
throw new RuntimeException(e);
}finally {
try {
if(in!=null){
in.close();
}
if(reader!=null){
reader.close();
}
if(bufferedReader!=null){
bufferedReader.close();
}
if(pw!=null)
pw.close();
if(out!=null)
out.close();
}catch (IOException ex){
ex.printStackTrace();
}
}
}
//将指定的文件输出到输出流中
private void response200(OutputStream outputStream,String filePath,String ext){
PrintWriter pw = null;
//准备输入流读取磁盘上的文件
InputStream in = null;
InputStreamReader reader = null;
BufferedReader bufferedReader = null;
try{
if(ext.equals("jpg") || ext.equals("png") || ext.equals("gif")){ //图片用字节流输出
outputStream.write("HTTP/1.1 200 OK \r\n".getBytes()); //输出响应行
if(ext.equals("jpg"))
outputStream.write("Content-Type: image/jpg\r\n".getBytes());
else if(ext.equals("png"))
outputStream.write("Content-Type: image/png\r\n".getBytes());
else if(ext.equals("gif"))
outputStream.write("Content-Type: image/gif\r\n".getBytes());
//输出一个空行,表示响应头结束
outputStream.write("\r\n".getBytes());
//利用字节输入流读取文件内容,并且输出到输入流中
//创建输入流
in = new FileInputStream(filePath);
int len = -1;
byte[] buff = new byte[1024];
while((len = in.read(buff))!= -1){
outputStream.write(buff,0,len);
outputStream.flush();
}
}else if(ext.equals("html") || ext.equals("js") || ext.equals("css") || ext.equals("json")){
pw = new PrintWriter(outputStream);
pw.write("HTTP/1.1 200 OK \r\n"); //输出响应行
if(ext.equals("html"))
pw.println("Content-Type: text/html;charset=utf-8");
else if(ext.equals("js"))
pw.println("Content-Type: application/x-javascript");
else if(ext.equals("css"))
pw.println("Content-Type: text/css");
else if(ext.equals("json"))
pw.println("Content-Type: application/json;charset=utf-8");
//输出一个空行,表示响应头结束
outputStream.write("\r\n".getBytes());
//初始化输流
in = new FileInputStream(filePath);
reader = new InputStreamReader(in);
bufferedReader = new BufferedReader(reader);
//写出数据
String line = null;
while ((line = bufferedReader.readLine())!=null){
pw.println(line);
pw.flush();
}
}else{
response404(outputStream);
}
pw.write("Content-Type: text/html;charset = utf-8");
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(pw!=null)
pw.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
//响应404页面
private void response404(OutputStream outputStream){
PrintWriter pw = null;
try{
pw = new PrintWriter(outputStream);
pw.write("HTTP/1.1 404 \r\n"); //输出响应行
pw.write("Content-Type: text/html;charset = utf-8");
pw.println();//输出空行 表示响应头结束,开始响应内容
pw.write("<h2>resource is not exist!</h2>");
pw.flush();
}catch (Exception e){
e.printStackTrace();
}finally {
try{
if(pw!=null)
pw.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}