java 如何发现本地网络上的 Web 服务器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2717459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to discover web servers on a local network?
提问by Stefan Kendall
Suppose I'm running several servers serving basic requests on my local network (say a home network, where all machines generally have an IP in the form K.K.K.x, where x is variable). Is there an easy way to discover all such servers? I would need to find each IP on the network running a particular java server application.
假设我在本地网络(例如家庭网络,其中所有机器通常具有 KKKx 形式的 IP,其中 x 是可变的)上运行多个服务器来处理基本请求。有没有一种简单的方法来发现所有这些服务器?我需要在运行特定 java 服务器应用程序的网络上找到每个 IP。
采纳答案by John Weldon
So you have a class C network... just attempt to open the particular server applications port on each IP address between 1 and 254. If you want to get fancy, you can do some checks to verify that if the port actually opens, it does what you expect for that application.
所以你有一个 C 类网络......只需尝试在 1 到 254 之间的每个 IP 地址上打开特定的服务器应用程序端口。如果你想花哨的话,你可以做一些检查来验证端口是否真的打开,它执行您对该应用程序的期望。
回答by Trey Hunner
Are you looking for a solution within your Java application? If you are simply looking for a one-time solution, nmap should work.
您是否正在 Java 应用程序中寻找解决方案?如果您只是在寻找一次性解决方案,nmap 应该可以工作。
If your local network is of the form 192.*.*.* try this (I added sudo because it must be run as root):
如果您的本地网络的格式为 192.*.*.* 试试这个(我添加了 sudo 因为它必须以 root 身份运行):
sudo nmap -vv -sS -O -n "192.168.1.1/24"
回答by BalusC
Since not every webserver listens on a fixed port of 80, you'll need to scan ports. Open (and close!) in a loop a socket on every port, you can use java.net.Socketfor this. If success, then fire a simple GET request on /on the IP/port in question, you can use java.net.URLConnectionfor this. If you receive a valid HTTP response (regardless of the status code), then it's a webserver. You can determine the server type by the Serverheader in the HTTP response. You however need to take into account that the default response header can be spoofed/removed/changed by the server admin.
由于并非每个网络服务器都侦听 的固定端口80,因此您需要扫描端口。在每个端口上循环打开(并关闭!)一个套接字,您可以使用java.net.Socket它。如果成功,则/在有问题的 IP/端口上触发一个简单的 GET 请求,您可以使用java.net.URLConnection它。如果您收到有效的 HTTP 响应(无论状态代码如何),那么它就是一个网络服务器。您可以通过ServerHTTP 响应中的标头确定服务器类型。但是,您需要考虑到服务器管理员可以欺骗/删除/更改默认响应标头。
Note that some firewalls may recognize the scanning pattern of a port scanner and block this.
请注意,某些防火墙可能会识别端口扫描器的扫描模式并阻止它。
回答by jweyrich
There are 2 basic ways to achieve this, and both require you to send/receive packets to/from each host you want to check.
有两种基本方法可以实现这一点,两者都要求您向/从要检查的每个主机发送/接收数据包。
The simplest approach is trying to establish the TCP connection to the desired port, as you'd normally do.
A more complicated and fancy approach, but faster in terms of execution, is sending a SYN packet, and waiting for a response packet. If the response is a SYN/ACK, it means the port is open (waiting for a connection), otherwise, it isn't. However, Java doesn't provide the necessary API (see raw socket) for this. You'd have to find a library/wrapper or write one using C and JNI.
最简单的方法是尝试建立到所需端口的 TCP 连接,就像您通常所做的那样。
一种更复杂、更奇特但执行速度更快的方法是发送 SYN 数据包,然后等待响应数据包。如果响应是 SYN/ACK,则表示端口是打开的(等待连接),否则不是。但是,Java 没有为此提供必要的 API(请参阅原始套接字)。您必须找到一个库/包装器或使用 C 和 JNI 编写一个。
For more insights to the 2nd option, read this.
有关第二个选项的更多见解,请阅读此内容。
回答by systempuntoout
I would scan IP rangeand test Socket connection to port 80 with a code like this:
我会扫描 IP 范围并使用如下代码测试到端口 80 的 Socket 连接:
try {
s = new Socket(addr,80);
System.out.println("Webserver found on IP:" + addr );
s.close();
}
catch (IOException ex) {
System.out.println("Webserver NOT found on IP:" + addr );
}

