随着互联网的发展,对于文件的保存和获取都可以通过网络来实现,例如通过网盘。用户可以把网盘看成一个放在网络上的硬盘或U盘,不管你是在家中、单位或其它任何地方,只要你连接到因特网,你就可以管理、编辑网盘里的文件。不需要随身携带,更不怕丢失。
这个项目目的是基于HTTP1.1协议实现一个简易的网盘,主要实现的功能是:
- 可以通过网页查看当前网盘中的资源,以HTML页面的形式展现出来,可以进行差错处理。
- 实现通过网页将网盘上的文件下载到本地。
- 通过网页将本地文件上传至个人网盘。
项目基本框架:
程序开始---》 创建线程池---》 搭建TCP服务器---》 接受HTTP数据并解析HTTP请求---》 进行业务处理并返回处理结果:1.申请文件列表,2.文件下载,3.文件上传。
项目实现简述:
通过封装的类来实现特定的功能。
class ThreadPool:线程池类。创建一定数量的线程,使用线程安全的队列将创建好的线程组织成任务队列,当任务来时,添加任务进入任务队列,队列中的线程处理任务。解决线程过多会带来调度开销,提高程序的性能,同时阻止过多的请求使网盘资源耗尽导致崩溃。
class HttpTask:HTTP请求处理的任务,任务队列中的成员。包含客户端socket,包含任务处理接口。(初始化完添加到任务队列)
class HttpServer:建立一个TCP服务端,初始化线程池,并持续接受新连接,将新的连接组织成一个线程池任务,并添加到线程池中。
struct RequestInfo:用来接受保存从HTTP请求头部中解析出的请求信息。包含请求方式、协议版本、资源路径、资源实际路径、查询字符串、整个头部的键值对。
class HttpRequest:用于接受并解析客户端发送的HTTP请求数据,包含HTTP数据的接受接口、HTTP数据的解析接口以及对外提供能够获得处理结果的接口。
class HttpResponse:用于响应客户端的请求。包含文件请求(文件下载和显示文件列表)接口、CGI(用于上传文件)接口。
class Utils:提供一些公用的接口,功能为:分割字符串、获取错误码、转换格林威治时间、获取文件ETag,根据文件后缀获取文件类型。
class Upload:接受客户端上传的文件数据并解析,在请求的服务器位置创建文件,将上传的文件内容写入创建的新文件中,完成文件上传。
关于HTTP
HTTP:即超文本传输协议,是互联网上应用最广泛的网络协议。它是应用层的协议,底层是基于TCP通信的。HTTP协议的工作过程:客户通过浏览器向服务器发送文档请求,浏览器将请求的资源回应给浏览器,然后关闭连接。即:连接->请求->响应->关闭连接。
HTTP请求头部:头部分为首行和头部(如图),首行包含请求方法、url、协议版本,头部包含请求的属性,通过冒号分隔的键值对表示。
HTTP响应头部:除了首行与请求时不同,响应的头部包含:协议版本号、状态码、状态码解释。
项目流程
- 客户端请求连接,当服务器连接上客户端时,将客户端的socket处理成一个任务,发送给线程池,线程池接收到任务后,唤醒一个线程去执行任务。
- 当客户端发送请求时,线程调用HttpRequest的接口来接收HTTP请求的数据,解析请求头部,获取请求方法、url、协议版本以及请求的属性,并将有用的信息保存在RequeInfo中。
- 调用HttpResponse中的接口,通过保存在Info的信息来判断请求的目的,判断请求方式是POST或GET,如果是GET判断获取的资源是否是目录、文件。当请求方式为GET时,若url是一个目录,就将目录内容以HTML格式发送给客户端,若url是一个文件,则实现文件下载功能。当请求方式为POST时,url是服务器目录下的一个cgi程序,则执行文件上传功能。
CGI程序工作过程:
结果展示
源码链接:
https://github.com/zy67/hahaha/tree/master/HTTPAERVER