Httpd 服务器是:C/S 架构的,通常客户端与服务端都不会在同一台主机上,那么意味客户端与服务端的数据通讯是跨网络的。那么服务端与客户端是如何解决数据通讯问题呢。使用:基于socket机制借助于IPv4或IPv6协议实现不同主机进程间数据通讯的。Socket地址格式如下:
IPv4 Domain IPv4地址:0~65535端口 IPv6 Domain IPv6地址:0~65535
例:172.16.13.1:41957 《==========》192.168.60.99:80
IP地址是用来标识跟网络上的主机的,端口号是标识该主机的用户空间的应用程序的地址;这样使用 IP +端口号,就可以找到指定主机的指定应用程序了。Httpd服务器的虚拟主机是调整 IP + 端口号的不同组合实现基于端口的虚拟主机和基于IP地址的虚拟主机的。如:
一、设置虚拟主机前的配置;
(1)、 注释掉主配置文件中的【DocumentRoot】定义的网页文档目录
# DocumentRoot /var/www/html
(2)、在主配置中设置监听的端口与所使用的IP地址;
Listen 80 Listen 192.168.60.99:8080
查看监听的端口:
[root@stu13 ~]# netstat -anpt| grep httpd tcp 0 0 192.168.60.99:8080 0.0.0.0:* LISTEN 4026/httpd.worker tcp 0 0 :::80 :::* LISTEN 4026/httpd.worker
二、 配置基于IP的虚拟主机;
<VirtualHost 192.168.60.99:80> DocumentRoot /web/vhosts/www1 ServerName bbs.9527du.com ErrorLog / var/log/httpd/www1.err CustomLog /var/log/httpd/www1.access common </VirtualHost>
测试:
[root@stu13 ~]# curl -I http://192.168.60.99/index.html HTTP/1.1 200 OK Date: Wed, 13 Aug 2014 00:51:25 GMT Server: Apache Last-Modified: Mon, 11 Aug 2014 08:49:40GMT ETag: "1e-17-50056a2b04222" Accept-Ranges: bytes Content-Length: 23 Content-Type: text/html; charset=UTF-8
三、 匹配基于端口的虚拟主机;
<VirtualHost 192.168.60.99:8080> DocumentRoot /web/vhosts/www2 ServerName www.9527du.com ErrorLog /var/log/httpd/www2.err CustomLog /var/log/httpd/www2.access common </VirtualHost>
测试:
[root@stu13 ~]# curl -Ihttp://192.168.60.99:8080/index.html HTTP/1.1 200 OK Date: Wed, 13 Aug 2014 01:20:24 GMT Server: Apache Last-Modified: Wed, 13 Aug 2014 01:05:05GMT ETag: "16-23-5007860eece9f" Accept-Ranges: bytes Content-Length: 35 Content-Type: text/html; charset=UTF-8
说明:httpd2.4还要做网页文件目录的访问控制,否则创建虚拟机失败。
四、在httpd 2.4 版本建立虚拟主机
(1)、注释掉主配置文件中【DocumentRoot】定义的网页文档存在目录
#DocumentRoot /usr/local/httpd2.4/htdocs
(2)、虚拟主机配置如下
<VirtualHost 192.168.60.99> DocumentRoot /web/vhosts/www2 ServerName bbs.9527du.com ErrorLog /var/log/httpd/www2.err CustomLog /var/log/httpd/www2.access common </VirtualHost>
测试
[root@stu13bin]# curl -I http://192.168.60.99/index.html HTTP/1.1 403 Forbidden Date: Wed, 13 Aug 2014 01:52:21 GMT Server: Apache/2.4.1 (Unix) PHP/5.4.26 Content-Type: text/html; charset=iso-8859-1
说明:http的状态码为:403 Forbidden。无权访问资源
(3)、给虚拟主机的网页存放目录增加访问控制
<VirtualHost 192.168.60.99> DocumentRoot /web/vhosts/www2 ServerName bbs.9527du.com ErrorLog /var/log/httpd/www2.err CustomLog /var/log/httpd/www2.access common <Directory "web/vhosts/www2"> AllowOverride none Require all granted </Directory> </VirtualHost>
(4)、测试
[root@stu13 bin]# curl -Ihttp://192.168.60.99/index.html HTTP/1.1 200 OK Date: Wed, 13 Aug 2014 02:10:11 GMT Server: Apache/2.4.1 (Unix) PHP/5.4.26 Last-Modified: Wed, 13 Aug 2014 01:05:05GMT ETag: "23-5007860eece9f" Accept-Ranges: bytes Content-Length: 35 Content-Type: text/html
五、创建基于主机名的虚拟主机。IP地址和端口也不变化。主机名称发生变化。
在浏览器中访问 http://web.9527du.com/index.htm,首先会去联系DNS域名解析服务器解析 web.9527du.com 域名解析服务器会把解析结果返回给客户端。浏览器就使用IP地址访问该域名对应的主机的资源。但是,web服务器有三台虚拟主机:
基于IP地址虚拟主机 192.168.60.99:80 基于端口虚拟主机 192.168.60.99:8080 基于域名的虚拟主机 web.9527du.com(它的IP地址是:192.168.60.99:80)
问题:基于主机名的虚拟主机的IP地址端口号与基于IP地址的虚拟主机是相同的。浏览器是使用DNS解析后的IP地址去联系对应的web服务器的,在浏览器中输入:http://web.9527du.com/index.html就访问到基于域名的虚拟主机了,而没有访问到基于IP地址的虚拟主机中的资源呢?其实,客户端从服务器获取资源是通过 HTTP协议的首部来交互的。如下图所述:
说明:数据包中封装了HTTP协议的头部信息,客户端与服务端的数据交互是通过HTTP协议定义的很多首部来交互数据的。如下面http的首部。
GET /image/mm.gif 服务器根据该首部就知道客户端请求的资源(uri)是什么 HOST:www.9527du.com 与httpd服务器中【ServerName】指令定义的主机名称做匹配如果匹配到 ,客户端请求的就是该主机下的资源。
这也就是为什么,基于IP地址的虚拟主机的socket地址与基于域名的虚拟主机的socket相同,访问到的虚拟主机是基于域名的虚拟主机上的资源而不是访问基于IP地址的虚拟主机上的资源。
(1)、开启基于域名的虚拟主机
NameVirtualHost192.168.60.99:80
注意:httpd 2.4 版本没有该指令。直接是打开基于域名的虚拟主机的功能的。
(2)、为了测试,在/etc/hosts文件中添加一行
[root@stu13~]# echo "192.168.60.99 web.9527du.com" >> /etc/hosts
(3)、配置虚拟主机
<VirtualHost192.168.60.99:80> DocumentRoot /web/vhosts/www3 ServerName web.9527du.com ErrorLog /var/log/httpd/www3.err CustomLog /var/log/httpd/www3.access common </VirtualHost>
(4)、测试
添加测试网页
[root@stu13~]# echo "host is www3" > /web/vhosts/www3/index.html
访问测试
[root@stu13~]# curl -eI http://web.9527du.com/index.html hostis www3
说明:
如果使用的httpd版本是2.4的话,一定要添加网页文件目录的访问控制。
OK!!!!