前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己写的小型静态服务器

自己写的小型静态服务器

作者头像
forrestlin
发布2018-05-23 17:45:01
1.3K0
发布2018-05-23 17:45:01
举报
文章被收录于专栏:蜉蝣禅修之道蜉蝣禅修之道

最近,由于计算机网络课程,自己动手写了一个静态服务器,感觉挺好玩的,慢慢了解到tomcat服务器的原理,而我这次做的只做了GET和PUT方法,废话不多说,下面上代码:

package com.xanxus.http; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class ThreadedServer { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8000); while (true) { Socket socket = serverSocket.accept(); new Thread(new SocketRunnable(socket, args[0])).start();// 注意,这里用内部类不行 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void putOutput(OutputStream outputStream, int stateCode, String fileType, String fileName, BufferedReader requestReader) throws IOException { String clientRequest = null; int contentLength = 0;// 请求实体长度 while ((clientRequest = requestReader.readLine()) != null) { // 获取实体长度 if (clientRequest.toLowerCase().startsWith("content-length")) { contentLength = Integer.parseInt(clientRequest .substring(clientRequest.indexOf(":") + 2)); } else if (clientRequest.equals("")) { // 空行,首部行结束 break; } } // 读取实体 File putFile = new File(fileName); FileOutputStream fos = new FileOutputStream(putFile); char[] requestEntity = new char[1024]; int count = 0; while (contentLength > 0 && (count = requestReader.read(requestEntity)) != -1) { fos.write(requestEntity.toString().getBytes()); contentLength -= count; } fos.close(); // 写响应报文 if (fileType != null) { // 输出首部行 StringBuilder stringBuilder = new StringBuilder(); switch (stateCode) { case 200: stringBuilder.append("HTTP/1.0 200 OK\r\n"); // mime type switch (fileType) { case "jpg": stringBuilder.append("Content-Type: image/jpeg" + "\r\n"); break; case "html": stringBuilder.append("Content-Type: text/html" + "\r\n"); break; case "gif": stringBuilder.append("Content-Type: image/gif" + "\r\n"); break; case "png": stringBuilder.append("Content-Type: image/png" + "\r\n"); break; default: stringBuilder.append("Content-Type: text/plain" + "\r\n"); break; } break; case 404: stringBuilder.append("HTTP/1.0 404 Not Found\r\n"); break; case 201: stringBuilder.append("HTTP/1.0 201 created\r\n"); break; } stringBuilder.append("Server: LFY/0.1\r\n"); stringBuilder.append("Connection: close\r\n"); stringBuilder.append("\r\n"); outputStream.write(stringBuilder.toString().getBytes()); outputStream.flush(); } outputStream.close(); } public static void getOutput(OutputStream outputStream, int stateCode, String fileType, String fileName) throws IOException { if (fileType != null) { // 输出首部行 StringBuilder stringBuilder = new StringBuilder(); switch (stateCode) { case 200: stringBuilder.append("HTTP/1.0 200 OK\r\n"); // mime type switch (fileType) { case "jpg": stringBuilder.append("Content-Type: image/jpeg" + "\r\n"); break; case "html": stringBuilder.append("Content-Type: text/html" + "\r\n"); break; case "gif": stringBuilder.append("Content-Type: image/gif" + "\r\n"); break; case "png": stringBuilder.append("Content-Type: image/png" + "\r\n"); break; case "avi": stringBuilder.append("Content-Type: video/x-msvideo" + "\r\n"); break; case "mp4": stringBuilder.append("Content-Type: video/mpeg" + "\r\n"); break; case "ogg": stringBuilder.append("Content-Type: audio/ogg" + "\r\n"); break; default: stringBuilder.append("Content-Type: text/plain" + "\r\n"); break; } break; case 404: stringBuilder.append("HTTP/1.0 404 Not Found\r\n"); break; case 403: stringBuilder.append("HTTP/1.0 403 Forbidden\r\n"); break; } stringBuilder.append("Server: LFY/0.1\r\n"); stringBuilder.append("Connection: close\r\n"); stringBuilder.append("\r\n"); outputStream.write(stringBuilder.toString().getBytes()); outputStream.flush(); // 文件存在才输出文件 if (stateCode == 200) { // 输出请求文件 int length = -1; byte[] fileContent = new byte[1024]; FileInputStream fis = new FileInputStream(fileName); // 一律用字节流,因为有可能请求二进制文件 while ((length = fis.read(fileContent)) != -1) { outputStream.write(fileContent, 0, length); } } else if (stateCode == 404) { // 输出404返回页面 String notFoundString = "<html><head><title>404</title></head><body><center><h1>Error:404 The requested URL was not found on this server.</center></body></html>"; outputStream.write(notFoundString.getBytes("UTF-8")); outputStream.flush(); } outputStream.flush(); } outputStream.close(); } } class SocketRunnable implements Runnable { Socket socket = null; String rootPath = null; public SocketRunnable(Socket socket, String rootPath) { // TODO Auto-generated constructor stub this.socket = socket; this.rootPath = rootPath; } @Override public void run() { // TODO Auto-generated method stub try { BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(socket.getInputStream())); OutputStream responseStream = socket.getOutputStream(); // 客户端发送的请求字符串,方法,请求文件路径,文件类型,主机名 String clientRequest = null, method = null, filePath = null, fileType = null, hostName = null; Boolean isConnection = false; StringBuffer responseBuilder = new StringBuffer(), fileContentBuilder = new StringBuffer();// 响应报文,请求文件内容 int stateCode = 200;// 状态码 Boolean isPut = false, isClf = false; // 获取首部行 if ((clientRequest = bufferedReader.readLine()) != null) { System.out.println("From:" + socket.getInetAddress().getHostAddress() + "\r\n\t" + clientRequest); // 第一行就返回 if (clientRequest.startsWith("GET") || clientRequest.startsWith("PUT")) { method = clientRequest.substring(0, 3); // 第一个斜杠的位置 int slashPosition = clientRequest.indexOf("/"); filePath = rootPath + clientRequest.substring(slashPosition, clientRequest.indexOf(" ", slashPosition)) .replace("/", "\\");// 把路径分隔符‘/’替换为‘\’ // 默认请求文件 if (filePath.equals(rootPath + "\\")) { filePath = rootPath + "\\index.html"; } File requestFile = new File(filePath); // 判断请求文件是否存在 if (!requestFile.exists()) { stateCode = 404; } fileType = filePath .substring(filePath.lastIndexOf(".") + 1); // 判断请求文件类型,设置输出的mime type switch (fileType) { case "html": case "htm": fileType = "html"; break; case "jpg": case "jpeg": fileType = "jpg"; break; case "gif": fileType = "gif"; break; } if (method.equals("GET")) { ThreadedServer.getOutput(responseStream, stateCode, fileType, filePath); socket.close(); } else if (method.equals("PUT")) { ThreadedServer.putOutput(responseStream, stateCode, fileType, filePath, bufferedReader); socket.close(); } } else if (clientRequest.equals("\r\n") || clientRequest.equals("")) { } } } catch (FileNotFoundException e2) { // TODO Auto-generated catch block e2.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

资源下载可以到http://download.csdn.net/detail/xanxus46/4745329

是否觉得很给力,以后有时间,一定会继续写动态的内容,如jsp,想一下都觉得兴奋。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012年11月08日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档