在网络编程中,经常需要在服务器里开一个端口,这里有一个问题,这个端口是开到哪个IP上面了,因为对于服务器来说经常是不止一个IP的,一个是127.0.0.1,一个是内网IP,比如192.168.1.3,一个是外网IP,比如211.19.56.39。对于开发着来说,经常会忽略绑定到具体某个IP上面,类似于下面的代码
ServerSocket serverSocket = new ServerSocket(8888);
//serverSocket.bind(new InetSocketAddress(8888));
在这种情况下,一般服务器会把此端口绑定到0.0.0.0上面,即在所有IP上面都绑定,即能在每个ip上面收到请求。
但是对于一般服务器来说,都会有定制服务器IP的功能,比如对内网IP的访问会宽松些,放些公司内部的资料,而对于外网IP来说,访问会相对的严格,限制较多。基于这样的需求,我做了一些实验,如下。
首先获得我电脑的所有ip和mac地址:
@Test
public void testNetwork2() throws Exception{
Enumeration<NetworkInterface> interfaces=NetworkInterface.getNetworkInterfaces();
while(interfaces.hasMoreElements()){
NetworkInterface in= interfaces.nextElement();
System.out.println("mac:"+bytesToHexString(in.getHardwareAddress()));
Enumeration<InetAddress> addrs=in.getInetAddresses();
while(addrs.hasMoreElements()){
InetAddress ia= addrs.nextElement();
if(ia instanceof Inet4Address){
System.out.println(ia.getHostAddress());
System.out.println("islookback:"+ia.isLoopbackAddress());
}
}
}
}
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
输出:
mac:null
127.0.0.1
islookback:true
mac:null
mac:null
mac:null
mac:null
mac:null
mac:null
mac:null
mac:null
mac:null
mac:00000000000000e0
mac:001aa027b7b6
10.11.2.63
islookback:false
mac:005056c00001
192.168.20.1
islookback:false
mac:null
mac:null
mac:null
mac:null
mac:null
mac:null
看到总共有3个ip 127.0.0.1 、10.11.2.63、192.168.20.1
实验一(在全网侦听):
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(8888));
serverSocket.accept();
在cmd里面输入netstat -ano -p TCP,输出如下:
协议 本地地址 外部地址 状态 PID
TCP 0.0.0.0:23 0.0.0.0:0 LISTENING 1936
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 936
TCP 0.0.0.0:8888 0.0.0.0:0 LISTENING 484
TCP 0.0.0.0:49163 0.0.0.0:0 LISTENING 1264
TCP 0.0.0.0:55571 0.0.0.0:0 LISTENING 2768
TCP 10.11.2.63:139 0.0.0.0:0 LISTENING 4
TCP 127.0.0.1:8307 0.0.0.0:0 LISTENING 2596
TCP 192.168.20.1:139 0.0.0.0:0 LISTENING 4
此次可以用所有ip进行访问此端口
实验二(在127.0.0.1侦听):
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("127.0.0.1",8888));
serverSocket.accept();
在cmd里面输入netstat -ano -p TCP,输出如下:
协议 本地地址 外部地址 状态 PID
TCP 0.0.0.0:23 0.0.0.0:0 LISTENING 1936
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 936
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 716
TCP 10.11.2.63:139 0.0.0.0:0 LISTENING 4
TCP 127.0.0.1:8307 0.0.0.0:0 LISTENING 2596
TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING 3948
TCP 192.168.20.1:139 0.0.0.0:0 LISTENING 4
这个时候只能通过127.0.0.1来访问此端口,别的IP不可访问
实验三(在10.11.2.63侦听):
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("10.11.2.63",8888));
serverSocket.accept();
在cmd里面输入netstat -ano -p TCP,输出如下:
协议 本地地址 外部地址 状态 PID
TCP 0.0.0.0:23 0.0.0.0:0 LISTENING 1936
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 936
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 716
TCP 10.11.2.63:139 0.0.0.0:0 LISTENING 4
TCP 10.11.2.63:8888 0.0.0.0:0 LISTENING 4324
TCP 127.0.0.1:8307 0.0.0.0:0 LISTENING 2596
TCP 192.168.20.1:139 0.0.0.0:0 LISTENING 4
这个时候只能通过10.11.2.63来访问此端口,别的IP不可访问
实验四(在192.168.20.1侦听):
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("192.168.20.1",8888));
serverSocket.accept();
在cmd里面输入netstat -ano -p TCP,输出如下:
协议 本地地址 外部地址 状态 PID
TCP 0.0.0.0:23 0.0.0.0:0 LISTENING 1936
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 936
TCP 10.11.2.63:139 0.0.0.0:0 LISTENING 4
TCP 127.0.0.1:8307 0.0.0.0:0 LISTENING 2596
TCP 192.168.20.1:139 0.0.0.0:0 LISTENING 4
TCP 192.168.20.1:8888 0.0.0.0:0 LISTENING 4652
这个时候只能通过192.168.20.1来访问此端口,别的IP不可访问
实验五(在192.168.20.1和127.0.0.1同时侦听):
new Thread(){
public void run() {
try {
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("127.0.0.1",8888));
serverSocket.accept();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("192.168.20.1",8888));
serverSocket.accept();
在cmd里面输入netstat -ano -p TCP,输出如下:
协议 本地地址 外部地址 状态 PID
TCP 0.0.0.0:23 0.0.0.0:0 LISTENING 1936
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 936
TCP 10.11.2.63:139 0.0.0.0:0 LISTENING 4
TCP 127.0.0.1:8307 0.0.0.0:0 LISTENING 2596
TCP 127.0.0.1:8888 0.0.0.0:0 LISTENING 1804
TCP 192.168.20.1:139 0.0.0.0:0 LISTENING 4
TCP 192.168.20.1:8888 0.0.0.0:0 LISTENING 1804
这个时候只能通过192.168.20.1和127.0.0.1来访问此端口,别的IP不可访问
至此,大家应该对如何获取主机所有ip和端口在哪个ip上面绑定进一步了解了吧。下面贴上jdk的关于ip和端口的几个类图以及关系。