以下文章来源程序员鱼皮 ,作者鱼皮
Bug 年年有,今年特别多。前段时间给大家分享过一个 特别坑的小 Bug,结果这两天我个倒霉蛋又遇到一个特别离谱的 Bug,有多离谱?大家可以看看视频:https://www.bilibili.com/video/BV1Fc411y7HS
官方省流:我的后端 Spring Boot 项目在 8101 端口启动,启动后可以访问 localhost:8101/api/v3/api-docs
得到接口文档的 JSON 数据,我的前端需要这份数据来生成请求代码。
结果呢,生成一直错误。经过一番排查,我发现前端没有正确获取到 JSON 数据,而是得到了一个 hello world 字符串。
这一下子给我整懵了,hello world 哪来的?
于是我就打开浏览器,访问地址:127.0.0.1:8101/api/v3/api-docs
,结果竟然返回了 hello world!
奇怪了,我的后端程序可没有输出 hello world 的代码呀。于是我通过命令查看哪些程序占用了 8101 端口:
哦,原来是一个叫 aDrive 的程序也占用了 8101 端口!
这是一个知名的网盘软件,只要在 MAC 电脑上运行它,你访问本地的 8101 端口就能看到 hello world 了。
看到这,真是让我哭笑不得,没想到我自己做项目时用的端口号竟然和别的程序冲突了。
话说为啥要占用这个端口来输出 hello world 啊,测试代码忘删了么?
好了,Bug 大概介绍到这,接下来讲点小知识。
在很多同学的认知中:
1)同一个端口只能被一个程序占用。
或者说:同一个端口只能启动 1 个 Tomcat,否则就会冲突。
2)访问 localhost 和访问 127.0.0.1 得到的响应是一致的。
我说的没错吧?
有这些认识很正常,很多工作多年的大佬如果没经历过这样的 Bug,也会这么认为。
但其实这 2 个认识都是错误的。
这句话缺少了重要的条件。不同的网络协议是可以共享同一端口的。
比如我这次遇到的情况是,aDrive 和我的后端程序使用的网络协议不同,分别为 IPv4 和 IPv6,所以并不会冲突。
同理,TCP 和 UDP 作为两种不同的传输层协议,也可以使用相同的端口号。
首先,localhost
和 127.0.0.1
完全是两个不同的概念!
localhost 是 主机名 (hostname),它通常被用来表示本地计算机,并且默认被解析到 127.0.0.1 这个地址。
但是你只要修改主机文件(hosts),就可以把 localhost 解析到其他地址,跟域名解析类似。
而 127.0.0.1 是 IPv4 的一个特殊的 IP 地址,直接指向本地回环接口,用于在本地进行网络通信。
为了兼容 IPv4 和 IPv6,我们访问 localhost 时,操作系统会首先尝试解析 IPv6 的回环地址 ::1
。如果系统不支持 IPv6,或者无法解析为 IPv6 地址,才会继续解析为 IPv4 的回环地址 127.0.0.1。
而直接访问 127.0.0.1 时,系统会默认解析到 IPv4 的回环接口。这才导致输入这两个地址时,使用的服务 / 访问到的内容不一样。
ok,就是这样一个小 bug,也能学到很多的知识,希望有用,学会还请点个赞吧~
注:在我看来,抓破皮的小BUG,我也经常遇到,特别是这篇文章说的小问题,在开发中会拖累很多时间,因此这些问题只有经验才能清楚,对于菜鸟来讲,确实个难题。
在未来,我也会经常更新一下小BUG,让大家也清楚,无论是工作的问题,还是自己的项目问题,都需要展现出来给大家看,这样就可以避免。