0x13-套接字编程-HTTP服务器(1)

这里不是百科全书,所以只会用最简单,最明了的语言,来讲最实用的TCP编程。

Echo程序太多,就不再重复了,贯穿整个章节的将会是一个 HTTP 服务器

这回是在Linux下开发,而不是Windows

TCP
  • 囫囵吞枣般的喂完UDP的基本应用,以及一些API的使用,不再赘述TCP的使用,其实是很多我也不懂,(逃。
  • 但是,对于API我一向抱以用多少学多少知多少的态度,人生如戏,重在看戏啊。
  • 如果想要查找具体的完整的API可以先去查,UNIX网络编程:卷1 + Linux Man手册,其中前者有一些部分实际上已经过时(内核版本跟不上)。更不用说后续加入Linux的一些接口,例如epoll。但是其他的接口还是可以参考的,并且十分的详细。
  • TCP,这是一个极其复杂的协议,说复杂是因为在这几十年的发展中,对其的优化已经多到令人发指,于此而言,虽说即便不知道这些优化也是可以编写程序,但是建议还是能够熟悉一下流程(两端交互的过程)
    • 三次握手,四次挥手,拥塞控制,滑动窗口机制。
    • 对于前两个而言,我个人有不同见解,于为什么是三次握手,而不是其他次数,但是由于并不一定被接受,所以我不在这里写入,有兴趣的可以Emali我一起讨论,在面试的时候,我也是会和面试官讨论这个问题,但一直没有满意的答案。

HTTP

  • 说了贯穿本章节的是一个 HTTP服务器,如此就一定要说说 HTTP协议 了,如果说前面的TCP即使你不懂它的原理也能编写一个能运行且效率不错的TCP程序的话,那么想写一个HTTP服务器,你要是不懂 HTTP协议,简直是寸步难行。

  • 最权威的莫过于 《HTTP权威指南》,你可别想着去看HTTP的标准草案了,那真是神鬼难懂。当然这本书亦是一部大块头,可以选择在网上找一些HTTP协议的资料来补充一些基本知识,再用这本大块头来检索自己需要了解的地方。

  • 简单说一下 HTTP 协议

    • 实际上这个协议就是 TCP协议在 应用层 的一种封装,换句话说 HTTP服务器实质上还是一个 TCP 程序,只不过 TCP协议 已经被操作系统实现好,留出借口来给你调用,而 HTTP协议 则是完全需要你自己编写。
    • 所谓协议就是双方都需要遵守的一个规则,所以 HTTP协议 实质上是一种非实际的东西,最主要的还是包括了一个 状态机,称为 HTTP状态机 ,它的作用就是 解析/生成 HTTP报文,不必太过注意这些名词,最开始想写这个程序的时候,也没有太多顾虑这种名词性的东西。
    • 所有的名词都是为了更好的抽象一件事物,就好比数学上的各种 符号,其实本没必要存在,但为了抽象简单的表达,符号就应运而生。所以当你理解不了一个符号的时候,就跳过他,因为你总能找到一个它的替代物(例如符号对应的 公式/展开式,符号对应的定理,定理对应的实际例子),而且比他更加的详细且好理解,这是我三年学习数学总结出来的经验。
    • 扯了一些没用的,回归正题
  • 协议版本号

    • 主流的就是 HTTP/1.0, HTTP/1.1,其他的在编写本程序时不必太在意
    • 需要了解的是这两个版本好的一些功能区别,例如最广为人知的Connection:的默认属性
  • 方法

    • GET
    • POST
    • HEAD
    • 实际上,在一般的服务器实现中,也只需要实现这三个方法就够了,特别是前两者比较重要,将以GET进行程序的方法编写,有兴趣的可以自己实现POST方法,我的源代码中也已经完成一半了,但并不打算继续完成。

有图有真相

GET / HTTP/1.1\r\n          <--- 这是状态行,包括一个请求方法,资源,协议版本
Host: www.wushxin.top\r\n   <-- 这是属性头,
Connection: keep-alive\r\n  <-- ...
\r\n                        <-- 一直到空行结束
  • 这是最简单的HTTP请求报文,整个报文的意思是请求 资源根目录(注意,是资源根目录) 下的资源(默认 请求根目录且不写什么资源就返回index.html),并希望与服务器保持连接

这里的保持连接和 TCP 协议中的保持连接不一样,具体可以去查找资料,简单来说这是一种不可靠的保持连接,双方都可以在做出保证之后,突然断开连接。可以把它当成不靠谱连接,但是表面工作还是要做的。

有图有真相

200 OK\r\n                  <-- 状态行,包括一个状态码,状态详情
Host: www.wushxin.top\r\n   <-- 属性,
Connection: close\r\n       <-- ...
Content-Length: 78\r\n      <-- 这个属性,代表空行后面数据有多少
\r\n                        <-- 直到空行
<html><body><p>Hello, That is the Resource which you Request!</body></html>
  • 这是很简单的一种返回报文,Content-Length属性在这里特别重要!绝对不能缺少,它给对端一种信息就是,这个报文的结束位置在哪里。

  • 在上述报文中,每行的末尾都有\r\n这是HTTP协议 用来表达行末的一个标志,而且,HTTP协议 的头部和文本部有一个空行\r\n来进行分割。

  • 以上就是所有我想要介绍的 HTTP协议的内容,有些零散,还是建议去查找一些资料后再来往下看。

详细计划

  • 上面的内容看起来有些零碎,但是做一个程序,还是需要理一理自己的思路。
  • 首先,我们的目的是做出一个 并发HTTP服务器, 会涉及到的知识点:
    1. HTTP协议的实现
    2. TCP的Socket编程(即套接字编程),所谓网络编程
    3. 多线程
    4. epoll 机制,暂时不要管selectpoll这两个相似功能的机制
      • FastCGI的实现(作为扩展,有兴趣的在最后可以去尝试,资源:FastCGI规范)

书籍推荐