这几天在倒腾一个简易的TCP通信,但出现了以下问题
1.服务器在localhost上开放了8888端口,但是用外网端口扫描却显示关闭,同时TCP连接IP:8888被拒绝,提示[WinError 10061] 由于目标计算机积极拒绝,无法连接。
2.在服务器上,用TCP连接127.0.0.1:8888,可以正常通信
3.服务器安全组已经把相应的端口开放,服务器防火墙处于关闭状态。
解决过程
先前以为只要在127.0.0.1/localhost开放相应的端口,对应IP:端口也能访问到
后来在快绝望的时候,无意间发现,自己搭建在服务器上的jupyter能够正常的开放端口,供外网访问到
于是根据这条线索,我先用命令去查看了相应端口的开放情况
netstat -an | grep XXXX(端口号)
发现这个端口竟然是开放在0.0.0.0下的
再一看自己想要开放的8888端口,就发现其中的不一样了
8888端口是开放在127.0.0.1上的。
于是,依样画葫芦,修改程序,把8888端口也开放在0.0.0.0上
再通过外网访问,终于成功了!!!
127.0.0.1与0.0.0.0区别
一个非常特殊的IP:0.0.0.0
表示该服务器上所有的IP地址.
比如一个tomcat配置文件中,如果监听的IP地址设置了 0.0.0.0 就表示你的这个tomcat服务器监听在本机的所有IP地址上,通过任何一个IP地址都可以访问到.
比如一个tomcat配置文件中,如果监听的IP地址设置了 0.0.0.0 就表示你的这个tomcat服务器监听在本机的所有IP地址上,通过任何一个IP地址都可以访问到.
我们在java编程中使用ServerSocket做网络侦听,通常只需要如下代码:
1 2 |
ServerSocket serverSock=new ServerSocket(8888); serverSock.accept(); |
假如我的主机ip为:10.10.152.8,
用以上代码做侦听,127.0.0.1:8888或者10.10.152.8:8888都可以连上,
但大家有没有想过过,这个ServerSocket到底使用哪个IP在做侦听?
如果我们将以上代码改成显式绑定:
1 2 3 4 5 6 |
ServerSocket ss=new ServerSocket(); String ip=“10.10.152.8″; int port=8888; InetSocketAddress addr=new InetSocketAddress(ip,port); ss.bind(addr); ss.accept(); |
你会发现,127.0.0.1:8888是无法访问的,
而如果将ip改成127.0.0.1,那么10.10.152.8:8888是无法访问的。
实际上,背后的秘密就在与0.0.0.0这个IP,他可以代表本机的所有IP地址,
但这个IP并不是真是存在的,我们ping不通它,如果将ip改成0.0.0.0:
1 2 3 4 5 6 |
ServerSocket ss=new ServerSocket(); String ip=“0.0.0.0″; int port=8888; InetSocketAddress addr=new InetSocketAddress(ip,port); ss.bind(addr); ss.accept(); |
我们会发现,这和默认行为是一样的,127.0.0.1:8888或者10.10.152.8:8888都可以连上。
而127.0.0.1是回送地址
即主机IP堆栈内部的IP地址,主要用于网络软件测试以及本地机进程间通信,无论什么程序,一旦使用回送地址发送数据,协议软件立即返回之,不进行任何网络传输。
如果还是不行
- 检查云服务器控制台中,安全组的配置
- 检查服务器中防火墙的设置
- 检查网络连接的情况