怎么做?试着写一些思路。

参考:http://www.cnblogs.com/chenpi/p/5602171.html

一、具体实现思路

  1. 创建一个ServerSocket对象。
  2. 调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待。
  3. 从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应。
  4. 处理请求:读取InputStream字节流信息,转成字符串形式,并解析,这里的解析比较简单,仅仅获取uri(统一资源标识符)信息。
  5. 处理响应:根据解析出来的uri信息,从WEB_ROOT目录中寻找请求的资源资源文件, 读取资源文件,并将其写入到OutputStream字节流中。
  6. 关闭Socket对象。
  7. 转到步骤2,继续等待连接请求。

二、具体实现

(1)实现一个HttpServer类,负责监听端口,调用模块对请求进行处理

要注意链接的释放顺序。后创建的先释放。

(2)实现一个类保存常量

(3)实现一个请求解析类

这个类可以对请求进行处理,通过parse方法获取请求的信息:

再通过parseUri方法获取请求资源的路径:

(4)实现一个请求处理类

三、遇到的一些问题

(1)返回的内容长度不符

Content-Length如果存在并且有效的话,则必须和消息内容的传输长度完全一致。

经过测试,如果过短则会导致内容截断(一些内容可能无法显示),过长则会导致请求超时,浏览器将一直处于等待状态。

Content-Length的值应为内容整体的长度(从<html>到</html>的整体长度,空格等包含在内)。

举个例子,这次使用的文件为index.html:

其长度为110,即Content-Length长度应为110。如果不为110,可能引发问题。

具体请看:

http://www.xie4ever.com/2017/05/14/java-%E5%88%86%E6%9E%90%E4%B8%8A%E6%AC%A1%E7%9A%84%E7%AE%80%E5%8D%95%E6%9C%8D%E5%8A%A1%E5%99%A8/

(2)需要及时关闭链接,否则可能造成链接泄露

以前也说过,不能这样写:

如果socket释放报错,将直接跳到catch部分,剩下的inputStream和outputStream的释放方法就被跳过了。

应遵从后新建先释放的原则,改为:

四、总结

虽然这个简单服务器存在很多问题,但是在编码的时候我成功巩固了知识。

同样是实现静态资源服务器,对比一下go的实现,可以感受一下java实现的复杂程度…

http://www.xie4ever.com/2016/05/17/go-%E8%AE%BF%E9%97%AE%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90/