刚刚发现一个有趣的现象,测试django项目的时候,这样启动服务器:

$ python3 ./manage.py runserver
...
Starting development server at http://127.0.0.1:8000/
...

然后想起laravel项目也是8000端口,就同时启动laravel项目:

$ php artisan serve
Laravel development server started on http://localhost:8000/

问题来了,2个端口一样,按理说应该会冲突啊,可是没有,打开浏览器,输入127.0.0.1:8000,看到的是django的项目。那么laravel项目哪去了,难道没启动成功,可是又没报错?

仔细看laravel的输出信息,于是浏览器输入localhost:8000,果然,是laravel的项目,也就是说,127.0.0.1 != localhost?这不可能吧。

于是我用netstat看一下,到底是什么情况。

$ netstat -apn | grep 8000
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      5374/python3
tcp6       0      0 ::1:8000                :::*                    LISTEN      5518/php7.0

从输出信息看,确实都是8000端口,但是地址没发生冲突,也就是说django项目默认是用ipv4127.0.0.1地址,laravel项目默认用的是ipv6地址::1,地址不一样,那么端口相同也可以。

然后我关掉这2个项目,单独启动laravel项目,发现默认用的就是ipv6地址,也就是说不能用127.0.0.1来访问,可以考虑用这2个地址访问:

看了下wiki上的Localhost介绍,操作系统的hosts文件中的localhost解析一些ip

127.0.0.1    localhost
::1          localhost

那么问题来了,解析localhost是不是有个优先级问题呢?我发现当laravel项目启动的时候,默认是解析成ipv6的地址::1,而开启django项目的时候,才会解析成ipv4的地址127.0.0.1

考虑到其他框架可能会占用8000端口,那么有可能laravel采用了默认利用ipv6地址,从而避免启动端口冲突问题;然而localhost先解析ipv6,从而避免访问冲突问题,真是机智。。。

所以需要用这种方式对laravel项目做端口映射就要注意了,用--hosts参数指定ip,例如:

$ php artisan serve --host=127.0.0.1

那么dns是否会优先解析ipv6呢?我猜应该是的,因为ipv6正在慢慢普及。