如何检查 Java 中是否存在 TCP/IP 服务器
How to check if a TCP/IP server exists in Java
所以我创建了一个简单的 TCP/IP 服务器,它在后台 运行,我打算只在 LAN 上使用它,所以我不需要转发端口。但是,我仍然需要知道服务器 运行 来自的 IP,以便我可以从 LAN 上的另一台计算机进行连接。此外,我不想将 IP 硬编码到程序中,因为有时我可能想更改 运行 它的计算机。
我创建这个是为了检查我局域网上所有可能的 IP,并检查它上面是否有服务器 运行。 (控制台的输出是我只是检查它实际上是在联系服务器,所以我可以看到 IP 是正确的)
public void queryServers() {
System.out.println("Querying servers...");
String original192 = "192.168";
for(int subOne = 0; subOne <= 255; subOne++) {
for(int subTwo = 0; subTwo <= 255; subTwo++) {
System.out.println("Querying " + original192 + "." + subOne + "." + subTwo + ":5050");
String query = queryConnection(original192 + "." + subOne + "." + subTwo, 5050);
if(!query.equals("-")) {
System.out.println("Queried " + original192 + "." + subOne + "." + subTwo + ":5050 and received a response");
Main.queriedServers.add(query);
}else {
System.out.println("Queried " + original192 + "." + subOne + "." + subTwo + ":5050 but could not connect");
}
}
}
}
这基本上是获取本地 IP 地址的正常 192.168
部分,然后尝试所有可能的 IP 组合。
这是实际尝试连接到服务器的函数。如果连接成功,它会向它发回主机名和连接用户数等信息。
public String queryConnection(String ip, int port) {
try {
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("QUERY");
String resp = in.readLine();
return resp;
} catch (Exception e) {
return "-";
}
}
但是这种方法需要很长时间,因为它会尝试多次连接到服务器,然后才确定无法访问,因此为了检查所有可能的 IP,可能需要几个小时。
这是一种非常低效的方法,我想知道是否有任何更快的方法,或者我只能坚持对 IP 进行硬编码,我宁愿避免这种方法。
如果所有内容都安全地位于子网中(例如 192.168.x.x/255.255.0.0),多播是允许客户端和服务器找到彼此的一个很好的选择。
Oracle Java 教程是 here。本质上,服务器可以位于它喜欢的任何 IP 上,但它也加入了一个已知的 'multicast IP' 地址(例如教程中的 203.0.113.0)。这意味着它可以接收和回复小型多播数据包 (DatagramPackets)。
然后客户端可以向该多播 IP 发送一个 DatagramPacket 并期望来自服务器的回复,可能包含现在使用普通套接字连接的真实 IP 地址。
如开头所述,这确实需要客户端和服务器位于单个子网或支持多播的相关子网中。根据我的经验,这些天大多数人都这样做。
我的工作 - 我使用免费的动态 DNS 服务将服务器 IP 映射到自定义但稳定的主机名。所以当我从另一台计算机使用我的服务器时,我只需更改 DNS 服务中的 IP 地址。
如果您要在 LAN 上创建自己的服务器,您可以更有创意并使用 multicasting,您的客户端可以立即向整个 LAN 广播数据报请求,服务器可以使用其 IP 地址进行响应:)(一些集群协议以这种方式工作)
所以我创建了一个简单的 TCP/IP 服务器,它在后台 运行,我打算只在 LAN 上使用它,所以我不需要转发端口。但是,我仍然需要知道服务器 运行 来自的 IP,以便我可以从 LAN 上的另一台计算机进行连接。此外,我不想将 IP 硬编码到程序中,因为有时我可能想更改 运行 它的计算机。
我创建这个是为了检查我局域网上所有可能的 IP,并检查它上面是否有服务器 运行。 (控制台的输出是我只是检查它实际上是在联系服务器,所以我可以看到 IP 是正确的)
public void queryServers() {
System.out.println("Querying servers...");
String original192 = "192.168";
for(int subOne = 0; subOne <= 255; subOne++) {
for(int subTwo = 0; subTwo <= 255; subTwo++) {
System.out.println("Querying " + original192 + "." + subOne + "." + subTwo + ":5050");
String query = queryConnection(original192 + "." + subOne + "." + subTwo, 5050);
if(!query.equals("-")) {
System.out.println("Queried " + original192 + "." + subOne + "." + subTwo + ":5050 and received a response");
Main.queriedServers.add(query);
}else {
System.out.println("Queried " + original192 + "." + subOne + "." + subTwo + ":5050 but could not connect");
}
}
}
}
这基本上是获取本地 IP 地址的正常 192.168
部分,然后尝试所有可能的 IP 组合。
这是实际尝试连接到服务器的函数。如果连接成功,它会向它发回主机名和连接用户数等信息。
public String queryConnection(String ip, int port) {
try {
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.println("QUERY");
String resp = in.readLine();
return resp;
} catch (Exception e) {
return "-";
}
}
但是这种方法需要很长时间,因为它会尝试多次连接到服务器,然后才确定无法访问,因此为了检查所有可能的 IP,可能需要几个小时。
这是一种非常低效的方法,我想知道是否有任何更快的方法,或者我只能坚持对 IP 进行硬编码,我宁愿避免这种方法。
如果所有内容都安全地位于子网中(例如 192.168.x.x/255.255.0.0),多播是允许客户端和服务器找到彼此的一个很好的选择。
Oracle Java 教程是 here。本质上,服务器可以位于它喜欢的任何 IP 上,但它也加入了一个已知的 'multicast IP' 地址(例如教程中的 203.0.113.0)。这意味着它可以接收和回复小型多播数据包 (DatagramPackets)。
然后客户端可以向该多播 IP 发送一个 DatagramPacket 并期望来自服务器的回复,可能包含现在使用普通套接字连接的真实 IP 地址。
如开头所述,这确实需要客户端和服务器位于单个子网或支持多播的相关子网中。根据我的经验,这些天大多数人都这样做。
我的工作 - 我使用免费的动态 DNS 服务将服务器 IP 映射到自定义但稳定的主机名。所以当我从另一台计算机使用我的服务器时,我只需更改 DNS 服务中的 IP 地址。
如果您要在 LAN 上创建自己的服务器,您可以更有创意并使用 multicasting,您的客户端可以立即向整个 LAN 广播数据报请求,服务器可以使用其 IP 地址进行响应:)(一些集群协议以这种方式工作)