Linux C语言程序设计(二十)——基于Linux C的简单web服务器

1、HTTP的GET请求

        打开浏览器,输入服务器IP,例如 http://192.168.0.3 ,如果端口号不是80,例如是8000,则输入 http://192.168.0.3:8000 。这时浏览器向服务器发送的HTTP协议头如下:

GET / HTTP/1.1
Host: 192.168.0.3:8000
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

        注意,其中每一行的末尾都是回车加换行(C语言的"\r\n"):

第一行是GET请求和协议版本,其余几行选项字段我们不讨论,HTTP协议头的最后有一个空行,也是回车加换行。

我们实现的Web服务器只要能正确解析第一行就行了,这是一个GET请求,请求的是服务目录的根目录/(在本例中实际上是/var/www),Web服务器应该把该目录下的索引页(默认是index.html)发给浏览器,也就是把/var/www/index.html发给浏览器。假如该文件的内容如下(HTML文件没必要以"\r\n"换行,以"\n"换行就可以了)。


2、HTTP的GET应答

        HTTP头的第一行是协议版本和应答码,200表示成功,后面的消息OK其实可以随意写,浏览器是不关心的,主要是为了调试时给开发人员看的。虽然网络协议最终是程序与程序之间的对话,但是在开发过程中却是人与程序之间的对话,一个设计透明的网络协议可以提供很多直观的信息给开发人员,因此,很多应用层网络协议,如HTTP、FTP、SMTP、POP3等都是基于文本的协议,为的是透明性。

        HTTP头的第二行表示即将发送的文件的类型(称为MIME类型),这里是text/html,纯文本文件是text/plain,图片则是image/jpg、image/png等。

        然后就发送文件的内容,发送完毕之后主动关闭连接,这样浏览器就知道文件发送完了。这一点比较特殊:通常网络通信都是客户端主动发起连接,主动发起请求,主动关闭连接,服务器只是被动地处理各种情况,而HTTP协议规定服务器主动关闭连接。有些Web服务器可以配置成Keep-Alive的。

        如果浏览器请求的文件在服务器上找不到,要应答一个404错误页面。如下是一个应答范例:

HTTP/1.1 200 OK
Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: GET,POST,OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Request-Headers: *
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: keep-alive
Content-Length: 2928
Content-Type: text/html; charset=utf-8
Date: Sat, 19 Sep 2015 07:29:48 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: nginx/1.7.10
Set-Cookie: PHPSESSID=071udp6t82gdghcspl47s3he27; path=/
Set-Cookie: width=320; expires=Sat, 22-Mar-2025 12:49:48 GMT; path=/
Vary: Accept-Encoding
Vary: Accept-Encoding
X-Powered-By: PHP/5.4.40

3、简单的服务器源码

这个已经有了很多的示例代码了,其中有一个不错,推荐给大家:

点击打开链接


4、HTTP请求总结

服务器的开发过程中,大概注意这样的几点问题,如下:

1)解析浏览器的请求,在服务目录中查找相应的文件,如果找不到该文件就返回404错误页面
2)如果找到了浏览器请求的文件,用stat(2)检查它是否可执行
3)如果该文件可执行:
    发送HTTP/1.1 200 OK给客户端
    fork(2),然后用dup2(2)重定向子进程的标准输出到客户端socket
    在子进程中exec(3)该CGI程序
    关闭连接
4)如果该文件不可执行:
    发送HTTP/1.1 200 OK给客户端
    如果是一个图片文件,根据图片的扩展名发送相应的Content-Type给客户端
    如果不是图片文件,这里我们简化处理,都当作Content-Type: text/html
    简单的HTTP协议头有这两行就足够了,再发一个空行表示结束
    读取文件的内容发送到客户端
    关闭连接


猜你喜欢

转载自blog.csdn.net/ljtyzhr/article/details/48446209