监听端口问题续——根本原因
上一篇文章中用简单粗暴的方式解决了端口占用的问题,但是其实并没有找到问题的根本原因,并且使用的解决方法也具有明显的缺陷。
要找到根本原因,就需要从监听端口的本质TCP/IP协议入手。
简单来说Socket请求的目的地由IP地址和TCP端口两部分组成。TCP报文中只包含端口号,IP包中只包含IP地址。
所以如果程序监听端口时,如果端口相同,但是IP不同,则操作系统不会抛出端口被占用的异常。
重复上一篇文章中的例子,执行 netstat -an | grep 8989 查看8989端口的TCP/IP信息,如下
从图中可以明显发现,nc和ServerSocketChannel的IP是不同的,这样就证实了上面的观点。
可以通过在nc中指定IP地址来进一步证实,运行 nc -l 127.0.0.1 8989,预期的结果应该为系统抛出端口已占用的异常,真是运行的结果如下:
果然抛出了端口被占用的异常。
我们还可以再进一步,让nc监听网卡的IP的8I989端口,ServerSocketChannel监听127.0.01的8989端口。
使用命令ipconfig(windows上)或者ifconfig查看网卡IP,我的是192.168.3.25.
运行 nc -l 192.168.3.25 8989,启动NIOServer,查看端口情况:
使用telnet分别连接两个不同的IP和端口,效果如下:可以看到两个请求都成功了,上半部分是对nc的请求;下半部分是对ServerSocketChannel的请求。
从上面的内容我们可以得出疑似端口同时被多个程序占用的问题的根本原因就是IP地址不同。
从中我们可以学到,在监听端口时,一定要尽量明确指出IP地址,避免不必要的问题。