前两天学RMI的时候,看java core上说有一个简易的HTTP服务器,只有一个类文件。就像去瞧瞧,结果发现这个类里面有20+个内部类和接口。看了源代码之后,对http服务器的理解也更加深入了。源代码
NanoHTTPD 服务器的请求流程图
首先通过继承NanoHTTPD 类,自定义一个服务器启动的main入口,接下来继承NanoHTTPD里面的serve(HttpSession)方法 实现自定义的请求处理。
服务器启动之后,会简历一个监听线程(ServerRunnable),在这个线程内部监听 ServerScoket的连接。如果有客户端连接,就为每一个连接分配一个线程去处理连接请求。在这个连接线程里面,取得inputstream,和outputstream。
然后新建HttpSession对象,调用HttpSession对象的execute()方法, 在ClientHandler里面就用循环不断的监听接受到的这个Socket关闭了没有。
HttpSession对象然后根据inputstream里面的值,读取请求行,请求头,读完之后这两部分之后,就调用自定义的serve()方法调用解析请求body,
解析完body之后就需要返回Response,最后利用response里面的输出流,将返回的数据输出到 当前的Socket连接里面。最后就由浏览器来解析数据了。
将输出流,socket流,clienthandler线程依次关闭。完成一个处理
源码分析
NanoHTTPD.start(timeout,deamo)方法
|
监听线程(ServerRunnable)类
|
DefaultAsyncRunner类
做这个类就是为了提供一个可插拔的策略,可以统计当前的连接数,方便管理连接等
ClientHandler 线程
|
httpsession.execute()方法
|
serve(httpsession )方法
参数里面的hettpsession其实已经经过了请求行,和请求头的解析,只需要覆盖server方法里面,在里面解析请求body,处理我们自己的业务逻辑,比如说是post形式表单,那么表单数据在请求body里面,根据表单数据内容,返回响应的response对象,
HelloService重载的serve()方法
不过这个这个重载的方法没有调用解析请求body的方法,他只是简单的返回一个response对象
session 的 parseBody()方法
把所有请求体里面的内容,解析好,存放在files里面
返回的response 对象的send()方法
|
接下来就是关闭流,关闭socket,关闭线程的工作了。
现在看的还比较浅显,至于里面在解析请求头,请求行,请求体的时候的注意事项,编码方式,chunkedTransfer传输都了解的不深,接下来好好看一下。