最近,由于计算机网络课程,自己动手写了一个静态服务器,感觉挺好玩的,慢慢了解到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,想一下都觉得兴奋。

自己写的小型静态服务器相关推荐

  1. nodejs如何实现ajax,nodejs使用静态服务器处理ajax

    如需转载请注明来源与作者 上一次,手写了一个静态服务器.这次我们想更进一步:返回给前端ajax数据.注意:这里只是一个演示,所以所有ajax传入服务器的数据,我不会经过处理直接返回 文件夹 Tips ...

  2. Socket 简易静态服务器 WPF MVVM模式(一)

    整体代码下载 主要实现功能: Socket的简单应用 可修改IP和端口 显示来访信息 界面设计: 界面采用MVVM设计,很简陋. 前台的主要目的是 输入IP地址 输入端口 输入文件目录 开启监听和停止 ...

  3. node.js request get 请求怎么拿到返回的数据_从零开始用nodejs写一个简单的静态服务器

    nodejs搭建服务器第一步 const http = require("http")const PORT = 8000 const server = http.createSer ...

  4. 自主开发的小型Web服务器

    自主开发的小型Web服务器 1. 技术特点 2. 具体步骤 3. CGI技术 4. Mysql连接 5. Gitee原码链接 6. 参考Blog 1. 技术特点 网络编程(http协议,TCP/IP协 ...

  5. 项目--基于http协议的小型web服务器

    在我们对网络的学习过程中,会接触到网络编程,我们在网络中可以深刻认识到服务器与客户端的交互,当我们输入网址时背后发生的一系列后端操作,为了加深我们对网络部分的学习,我们找到了一个开源项目TinyWeb ...

  6. 构建静态服务器_为静态网站构建无服务器联系表

    构建静态服务器 介绍 (Introduction) A few years ago AWS launched static hosting service S3, which was a paradi ...

  7. 【Android RTMP】RTMPDump 推流过程 ( 独立线程推流 | 创建推流器 | 初始化操作 | 设置推流地址 | 启用写出 | 连接 RTMP 服务器 | 发送 RTMP 数据包 )

    文章目录 安卓直播推流专栏博客总结 一. Java 层传入的 RTMP 推流地址处理 二. RTMPDump 推流线程 三. 创建 RTMP 对象 四. 初始化 RTMP 对象 五. 设置 RTMP ...

  8. svn服务器搭建和使用_简单使用nodejs搭建一个静态服务器

    前提:系统安装nodejs 搭建步骤 使用nodejs搭建服务器,简单的来说可以分为三步: require相应的模块 创建服务器 配置端口 启动服务器 必要的nodejs模块 以下模块都是以 var ...

  9. 使用docker中的apline部署自己的golang的后端代码(添加制作静态服务器的注意点)...

    1.在window上写golang后端代码 2.打开终端设置临时的Linux的环境变量: SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 如下图所示 ...

最新文章

  1. 【ruby项目,语言提交检查(一)】怎样高速学习ruby ?
  2. 6个强大的PHP/Mysql代码生成器介绍
  3. Android开发技术周报 Issue#7
  4. python输出数据到excel-python如何导出数据到excel文件
  5. 【Java集合系列四】HashSet和LinkedHashSet解析
  6. Linux下NFS(网络文件系统)的建立与配置方法
  7. ant design 分页中文字_给你代码:ant-desgin-vue使用
  8. html中如何实现选择存储路径的功能_16687.VSM006分解03_如何打开HTML内嵌图像存储位置...
  9. 去授权美化版LM在线表白网页制作PHP源码
  10. 一步一步手绘Spring DI运行时序图(Spring 自动装配之依赖注入)
  11. 【GIS教程】土地利用转移矩阵
  12. 买哪个股票稳赚,三类股票,可以买了
  13. 华为5G空口新技术(2015年)
  14. [IOI2018]-day1 简要题解
  15. 快速上手 Android 蓝牙串口 SPP 开发
  16. 现代公关无需遮遮掩掩,明火执仗开干就行
  17. HEIC格式怎么转换?掌握这个方法,轻松实现!
  18. 期刊论文发表能加分吗
  19. crm客户关系管理系统总结
  20. Hadoop精华问答 | 如何设置单个任务占用的内存量和CPU数目?

热门文章

  1. 倾角传感器在工业的应用
  2. 后台业务账单和微信支付后台的订单对账步骤
  3. 通达信自动交易系统接口定义
  4. 深度学习--大黄蜂预测
  5. Nginx限制或允许IP或IP段访问
  6. mac上一款简单易用的卸载工具:
  7. 大数据从入门到实战——Hive综合应用案例 ——学生成绩查询
  8. idea启动Java web项目
  9. The following packages have unmet dependencies: deepin.com.wechat:i386 : Depends: deepin-wine:i386
  10. WPF TabControl 数据绑定