自己寫的一個HTTP文件服務器,在端口 50000上監聽HTTP連接請求,在Eclipse里面將程序正常地啟動之后,能夠在自己的機器上(Eclipse啟動該程序的機器上)訪問 50000端口,即FileServer能夠正常提供服務,可是在同一局域網下的其他機子則訪問不了。(FileServer運行的機器稱為本機,同一局域網內的機器稱為 其他機子)
本機狀態如下:
系統:Windows 7
防火牆狀態:已關閉
同一局域網的其他機子能夠 ping 通 本機。但是使用 telnet ip 50000 提示連接拒絕。
后面看到這篇文章:開放windows服務器端口-----以打開端口8080為例
按照操作把50000端口,添加防火牆例外設置之后,未果。因為我的防火牆本來就是關閉的啊,應該不是添加例外端口的原因吧。。。。。
於是,又把防火牆開啟,結果其他機子都ping不通本機了,更別說訪問 50000端口的服務了。
后來,把程序Eclipse導出jar包放到Linux上運行,也是同樣的結果---其他機子能ping通,但就是訪問不了FileServer的50000端口。
但該端口是正常運行的:
系統為CentOS,防火牆也已關閉。
使用telent ip 50000端口,提示:Connection Refused
原來問題的原因是:直接看代碼,
ChannelFuture f = b.bind("localhost", port).sync();
System.out.println("HTTP 文件服務器啟動, 地址是: " + "localhost:" + port + url);
代碼中使用了 localhost
把 localhost修改成本機的IP地址,問題解決。
ChannelFuture f = b.bind("10.0.12.160", port).sync();
System.out.println("HTTP 文件服務器啟動, 地址是: " + "http://10.0.12.160:" + port + url);
重新編譯,運行程序。不管在Windows下,還是在Linux下,都能訪問50000端口了。
其中,CentOS狀態是:防火牆關閉了的。
其中,Windows狀態是:防火牆關閉了的。
原因總結:
這其實不是防火牆的問題,因為防火牆已經關閉了。而是一個簡單的網絡地址問題:
localhost 本質上是個域名,理論上可以指向任何IP地址,只不過一般都是指的是環回地址:127.0.0.1,對於環回地址而言,其他計算機是不能訪問的!!!
假設程序中使用 localhost 作為bind()方法的綁定的參數,可以看到其端口啟動信息如下:
也就是說,這個50000端口綁定在了環回地址上!!!
這也是為什么 telnet 192.168.121.35 50000 提示Connection Refused的原因,因為50000端口在 127.0.0.1上。
把程序中使用IP地址(192.168.121.35)作為bind方法的綁定參數,啟動程序后,看到端口信息如下:
端口50000綁定的不再是環回地址了,而是一個IP地址。
那為什么能夠ping通 192.168.121.35 呢?當然能了,在同一個局域網里面,防火牆也是關閉的,網絡是正常的。
現在終於知道原來就算能ping通,ping命令說明到192.168.121.35地址沒有問題。但是我們的程序的端口是在 127.0.0.1這個地址上,這也是為什么盡管防火牆關閉了,其他機子還是訪問不了50000端口的原因。----環回地址只能在本機上使用。
寫程序時要細心,測試的時候用localhost,上線了就不要用了。
------------------------------------分割線-------------------------------
明白了 localhsot對應的就是 127.0.0.1之后,其實在代碼里面的 bind()方法也可以使用 "localhsot" 作為參數,並讓其他機子能夠訪問文件服務器(端口50000),只需要把 localhost 對應的地址127.0.0.1改成主機的IP地址就可以了。
比如, /etc/hosts文件的默認內容如下:
可以看到, localhost對應的就是 127.0.0.1
如果把它改成 192.168.121.35
那么,在程序中使用 "localhost"參數,其他機子也能訪問文件服務器的50000端口了。
也就是說:
127.0.0.1 是綁定在 loopback 接口上的地址,如果服務端套接字綁定在它上面,你的客戶端程序就只能在本機訪問。多簡單的原理!!細心就可以了!