首页 > 代码库 > java实现的HTTP简易服务器
java实现的HTTP简易服务器
程序有点BUG,欢迎高手指点,为啥不同的浏览器差别这么大?
运行服务器端程序后,在浏览器分别输入如下请求路径观察效果(我的服务器资源默认路径设置的是F:/project目录)。
http://localhost
http://localhost/myfile.txt
/* * 模拟一个HTTP服务器的实现 * 客户端(浏览器)请求服务器的文件,服务器端程序接受连接并处理,将相应的数据写入socket,发送给客户端 * 本Web服务器将入站连接放入池中,由一个RequestProcessor类实例从池中移走连接并进行处理 */ import java.io.*; import java.net.*; public class JHTTP extends Thread{ private File documentRootDirectory; private String indexFileName="index.html"; private ServerSocket server; private int numThreads =50;//设置服务器启动的线程数 public JHTTP(File documentRootDirectory,int port,String indexFileName) throws IOException{ if(!documentRootDirectory.isDirectory()){ throw new IOException(documentRootDirectory+" does not exist as a directory"); } this.documentRootDirectory=documentRootDirectory; this.indexFileName=indexFileName; this.server=new ServerSocket(port); } public JHTTP(File documentRootDirectory,int port) throws IOException{ this(documentRootDirectory,port,"index.html"); } public JHTTP(File documentRootDirectory) throws IOException{ this(documentRootDirectory,80,"index.html"); } public void run(){ //开启处理请求的线程,该线程会从socket池中取出一个socket连接,进行数据传输 for(int i=0;i<numThreads;i++){ Thread t=new Thread(new RequestProcessor(documentRootDirectory, indexFileName)); t.start(); } System.out.println("Accepting connections on port "+server.getLocalPort()+"..."); System.out.println("Document Root:"+documentRootDirectory); //服务器不停地接受请求 while(true){ try { Socket connection=server.accept(); RequestProcessor.processRequest(connection); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { File docRoot;//得到文档根 docRoot=new File("F:\\project"); //设置服务器的监听端口 int port; port=80; try { JHTTP webServer=new JHTTP(docRoot,port); webServer.start(); } catch (IOException e) { System.out.println("Server could not start because of an "+e.getClass()); System.out.println(e); } } }
//具体处理连接的线程类 import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; import java.io.*; import java.net.Socket; public class RequestProcessor implements Runnable { private static List pool = new LinkedList(); private File documentRootDirectory; private String indexFileName = "index.html"; public RequestProcessor(File documentRootDirectory, String indexFileName) { if (documentRootDirectory.isFile()) { throw new IllegalArgumentException( "documentRootDirectory must be a directory,not a file"); } this.documentRootDirectory = documentRootDirectory; // 返回此抽象路径名的规范形式 try { this.documentRootDirectory = documentRootDirectory .getCanonicalFile(); } catch (IOException e) { System.out.println(e); } if (indexFileName != null) { this.indexFileName = indexFileName; } } public static void processRequest(Socket request) { // 将对应于每一个客户端的socket连接放入池中,通知线程来处理他们 synchronized (pool) { pool.add(pool.size(), request); pool.notifyAll(); } } @Override public void run() { // 执行安全性检查,请求的文档不能超过根目录 String root = documentRootDirectory.getPath(); // 由于采用线程池的策略,所以说线程要不停地执行,以处理客户端的请求池(socket池)中的连接 while (true) { Socket connection; synchronized (pool) { while (pool.isEmpty()) { try { pool.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } connection = (Socket) pool.remove(0); } // 通过socket这个中介进行服务器客户端的数据交换 try { OutputStream raw; raw = new BufferedOutputStream(connection.getOutputStream()); Writer out = new OutputStreamWriter(raw); Reader in = new InputStreamReader(new BufferedInputStream( connection.getInputStream()), "ASCII"); // 存储客户端请求的第一行数据 StringBuffer requestLine = new StringBuffer(); int c; while (true) { c = in.read(); if (c == '\r' || c == '\n') break; requestLine.append((char) c); } String get = requestLine.toString(); System.out.println(get);// 记录请求的头一行(要对头行进行一些分解,如下) StringTokenizer st = new StringTokenizer(get); String method = st.nextToken(); String version = ""; // 本案例目前只处理GET请求 String filename; String contentType; if (method.equals("GET")) { filename = st.nextToken(); if (filename.endsWith("/")) filename += indexFileName; contentType = guessContentTypeFromName(filename); if (st.hasMoreTokens()) { version = st.nextToken(); } File theFile = new File(documentRootDirectory, filename.substring(1, filename.length())); if (theFile.canRead() && theFile.getCanonicalPath().startsWith(root)) { DataInputStream fis = new DataInputStream( new BufferedInputStream(new FileInputStream( theFile))); byte[] theData = http://www.mamicode.com/new byte[(int) theFile.length()];>java实现的HTTP简易服务器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。