查找侦听本地网络上特定端口的服务器
我有一个服务器应用程序。我还有一个客户端应用程序。当两个应用程序恰好位于同一网络上时,我能够在应用程序之间建立 tcp 连接。假设运行服务器应用程序的计算机正在端口 2121 上侦听新连接,并且其 LAN IP 地址为 192.168.0.120。在运行客户端应用程序的另一台计算机上,我将能够通过提供端口号 2121 和 IP 地址 192.168.0.120 来建立连接。
有没有办法找到网络上正在侦听端口 2121 的所有计算机?
我现在想到的一种算法是这样的:
获取当前计算机的 ip 地址,假设它的结果为 192.168.0.145。
现在服务器很可能会监听 IP 地址 192.168.0。?
然后在端口 2121 上 ping 192.168.0.1,然后在端口 2121 上 ping 192.168.0.2 ...然后继续。
不知道这个方法是否有效。此外,服务器可能恰好正在侦听 IP 地址 192.168.1.x
那么我必须对服务器和客户端应用程序进行哪些更改,以便客户端能够找到侦听端口 2121 的所有服务器?
I have a server application. I also have a client application. I am able to establish a tcp connection between the applications when both applications happen to be on the same network. so let's say that the computer running the server application is listening from new connections on port 2121 and it has the LAN ip address 192.168.0.120. On a different computer running the client application I will be able to establish a connection by providing port number 2121 and ip address 192.168.0.120.
Is there a way to find all computers on a network that are listening on port 2121?
One algorithm that I am thinking now is like:
get ip address of current computer and lets say it comes out as 192.168.0.145.
now most likely the server will be listening on ip addresss 192.168.0.?
then ping 192.168.0.1 on port 2121 then 192.168.0.2 on port 2121 ... and then keep going.
I don't know if that method is efficient. moreover there might be a possibility that the server happens to be listening on ip address 192.168.1.x
So what changes will I have to make to my server and client application so that the client is able to find all the servers listening on port 2121?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您提出的算法就是您需要的算法。问题之一在于候选 IP 地址的动态生成。
通常,可能的 IP 地址范围是子网掩码给出的范围 (http ://en.wikipedia.org/wiki/Subnetwork)。更准确地说,IP 中发生变化的部分是子网掩码中有 0 位时的部分(始终位于掩码末尾)。
在您的示例中:
192.168.0.*。
信息我认为导致您的问题的其他可能性有这些不同的范围:
回到查找“某些东西”是否正在侦听特定端口的问题的问题, ICMP 协议在这里并不是最好的,因为大多数防火墙都会过滤广播 ICMP 和单个 ICMP。 如果我们真正谈论的是服务器,您很可能必须手动打开您正在寻找的端口。此外,即使所有计算机都有响应,您仍然不知道它们是否托管您想要的服务。
下面的解决方案涉及计算候选 IP 地址的可能范围。之后您将遍历它们以查看是否可以连接到您的端口。
在此实现中,我按顺序进行测试,结果证明速度非常慢,因为如果主机未打开,连接超时为 30 秒。对于数百名候选人来说,这听起来不太好。但是,如果大多数主机可用(即使他们不托管您的服务),一切都会快几倍。
您可以通过找出如何减少此超时(我在分配的时间内找不到如何减少超时)或使用中提供的自定义超时来改进程序 如何配置套接字连接超时 。您还可以使用多线程并添加在线程安全集合中工作的地址并从那里使用它。
另外,您之前可以尝试 ping (ICMP),但可能会错过有效的服务器。
The algorithm you proposed is the one you need. One problem is in the dynamic generation of the candidate IP addresses.
Normally, the possible IP address range is the one given by the subnet mask ( http://en.wikipedia.org/wiki/Subnetwork ). More exactly, the part of the IP that change is that part when in the subnet mask you have 0bits (always at the end of mask).
In your example:
192.168.0.*.
The only other possibilities which cause your problem that I see to have these distinct ranges are:
Getting back to the problem of finding the problem of checking if "something" is listening on a specific port, the ICMP protocol is not the best here, as the majority of firewalls filter both the broadcast ICMP and single ICMP. If we are truly talking of a server, chances are you had to manually open the port you are looking for. Also, even if all computers respond, you still don't know if they host your wanted service.
The solution below involves computing the possible range of candidate IP addresses. After that you iterate through them to see if you can connect to your port.
In this implementation I test sequentially, which proves to be very slow as the timeout for connect is 30 seconds if the host is not on. For several hundred candidates, it doesn't sound too good. However, if the majority of host are available (even if they don't host your service), everything will go several times faster.
You can improve the program by either finding out how to decrease this timeout (I couldn't find out how in my allocated time) or to use a custom timeout as presented in How to configure socket connect timeout . You could also use multi-threading and adding the address that worked in a thread-safe collection and work with it from there.
Also, you could try pinging (ICMP) before, but you could miss valid servers.
(抱歉我的英语不好)我实际上需要类似的东西,并且刚刚发现了多播。 在这里您可以找到一篇文章和示例。文章中的示例应用程序在我的局域网上运行良好。我不知道它到底是如何工作的,但也许你可以从客户端多播一些东西,并让服务器用它的IP响应?或者,如果这不起作用,让服务器在一定的时间间隔内多播他的 IP 应该可以做到。抱歉,缺乏信息,我刚刚了解到这一点:)
(sorry for my bad english) I am actually needing something similar to this and just found out about multicast. Here you can find an article and example. The sample app from the article worked fine on my lan. I do not know exactly how it works but maybe you can multicast something from the client and have the server(s) to respond with its IP? Or if that do not work, have the server multicasting his IP in a timed interval should do it. Sorry for the lack of informations, i just learned about this :)
我在这里没有看到讨论的一个选项是拥有一个主服务器。
这个想法非常简单:应用程序的服务器可以在其中注册并且应用程序客户端可以在其中获取活动服务器列表的服务器。
需要记住的事情:
如果任何服务器与您的应用程序的任何其他服务器一样好,我建议该列表是根据从该服务器收到的最后一个问候消息的时间戳进行排序 - 这样客户端将在该列表的顶部显示最有可能仍然处于运行状态的服务器(因为它报告最后处于运行状态),并且可以随后沿着列表向下移动。
此外,每次主服务器收到列表更改的问候时,因此每隔一段时间客户端请求就会获得不同的服务器列表并使用不同的优先服务器,从而减轻全面服务器的负载。
An option i am not seeing beeing discussed here is to have a Master Server.
The idea is quite simple: A server where your application's server can register and where you application clients can get a list of active servers.
Things to keep in mind:
If any server is as good as any other for your application, i would advise the list to be ordered according to timestamp of last hello message received from that server - that way client will have at the top of that list the server most likelly to still be up (since it reported beeing up last) and can go down the list subsequentially.
More over, every time the Master Server receives an hello that list changes, so every so often client requests will get a different server list and use a different preferencial server, relieving load on servers accross the board.
不能用和获取ip时一样的方法吗?
让客户端发送广播 - 如果没有响应请等待
服务器接收广播并用自己的 IP 发回广播。
现在客户端知道服务器在外面并且在什么IP上。
can't you use the same method as when you get your ip.
let the client send a broadcast - if no response wait
server receive broadcast and send one back with its own ip.
now the client know that the server is out there and on what ip.
我假设你有一个服务器。如果您可以保证服务器位置(IP 地址和端口)恒定(或可以查找),那么每个客户端应用程序都可以通过连接到服务器并向服务器“注册”并通知服务器有关 IP 地址和本地端口的信息。打回来。
I assume you have a single server. If you can guarantee that the server location (ip address and port) is constant (or can be looked up) then each client application can 'register' with the server by connecting to it and informing the server about the ip address and local port to call back.
仅当计算机配置为响应 ping 时,ICMP Ping 才能确定计算机是否正在侦听特定端口。 ICMP 是一种协议,不同于 TCP 或 UDP。它对您的唯一用处是确定 IP 地址是否正在使用,即使这样也变得不太可行。
你有两个选择。
让客户端不断检查本地网络上的每个 IP 地址并尝试打开端口 2121。这不是一个好的选择。
让每台服务器向广播地址发送 ICMP ping,其中包含特定数据,宣布其已打开(并且可以选择不连接到客户端),但不要经常这样做(我建议测试一分钟,至少 5 分钟)生产)。您的软件所要做的就是查找广播 ping 并连接到发送 IP 地址。
更新:
ICMP Ping does not determine if a computer is listening on a specific port, only if the computer is configured to response to a ping. ICMP is a protocol, different then TCP or UDP. It's only use for you would be to determine if an IP Address is use, and even then is becoming less viable.
You have two options.
Have the client constantly check every IP address on your local network and try to open port 2121. This is not a good option.
Have every server send out a ICMP ping to the broadcast address with specific data announcing it is on (and optionally not connected to a client) the never every so often (I would recommend a minute for testing, and 5 minutes minimum for production). All your software has to do is look for the broadcast ping and connect to the sending IP Address.
Update:
你可以让服务器使用UDP将他的位置发送到特定端口,客户端监听它,然后客户端根据给定的ip和端口与服务器建立连接。
you can make the server send his location to a specific port using UDP, and the client listen to it then the client establish a connection with the server based on the given ip and port.