简体   繁体   English

多服务器发现 - Java / Android

[英]Multiple Server Discovery - Java/Android

I have an application where multiple servers could exist. 我有一个应用程序,可以存在多个服务器。 There are heaps of examples of how to use UDP to discover servers but it seems this only works with a single server. 有很多关于如何使用UDP来发现服务器的例子,但似乎这只适用于单个服务器。

What happens if multiple responses exist? 如果存在多个响应会发生什么? Are they queued, corrupted (with UDP pitfalls) or something else ? 它们是否排队,损坏(有UDP陷阱)或其他什么?

I would like to find out how to receive multiple responses from a UDP broadcast sent from an Android Device. 我想了解如何从Android设备发送的UDP广播中接收多个响应。 If this isn't viable, is there any other recommended approach for multiple server discovery for Android clients.. 如果这不可行,是否有任何其他推荐的方法用于Android客户端的多服务器发现..

Thank you 谢谢

I would first send a packet to all servers you want to ask if they are there, then let all servers respond. 我会首先将数据包发送到您想要询问的所有服务器,然后让所有服务器响应。 Since you want to find out how to receive the packages, here is how i would do that: 既然你想知道如何收到包裹,我会这样做:

long responseTimeout = 4000;
long start = System.currentTimeMillis();
while(true){
    long now = System.currentTimeMillis();
    if(now - start < responseTimeout){
        datagramSocket.setSoTimeout((int) (responseTimeout - (now - start));
    }else{
        break;
    }
    try{
        datagramSocket.receive(packet);
        addOnlineServer(packet.getAddress());
    }catch(SocketTimeoutException e){
        break;
    }
}

For a certain amount of time your android client should wait for responses, and add each ip of the received package to a list of online servers. 在一段时间内你的android客户端应该等待响应,并将收到的包的每个ip添加到在线服务器列表中。

Sure some of the packages could get lost as you are using UDP, but that's what you get. 当你使用UDP时,当然有些软件包可能会丢失,但这就是你得到的。 If you want to be sure that no packages get lost, use TCP instead. 如果您想确保没有包丢失,请改用TCP。

If you broadcast the message and the servers all return you should see all the responses as they come back. 如果您广播消息并且所有服务器都返回,您应该看到所有回复。

However be aware that UDP is a potentially lossy protocol and makes no guarantees at all. 但请注意,UDP是一种潜在的有损协议,根本不做任何保证。 Over a non-wireless LAN with decent switches it is pretty safe but as soon as it goes further than that (wireless, over multiple networks, etc) you can expect to lose at least some packets and any packet loss is a message loss on UDP. 通过具有良好交换机的非无线LAN,它是非常安全的,但是只要它超过(无线,多个网络等),您可能会丢失至少一些数据包,并且任何数据包丢失都是UDP上的消息丢失。

The usual solution to this is to send each message a few times. 通常的解决方案是每次发送几条消息。 So for example when you first start up you might broadcast at 1 second, 10 second, 30 seconds, and then every 10 minutes thereafter. 因此,例如,当您第一次启动时,您可以在1秒,10秒,30秒,然后每10分钟播放一次。 This will find servers immediately, then sweep up any it missed fairly fast, and then finally detect any new ones that appear on the network. 这将立即找到服务器,然后快速扫描任何错过的服务器,然后最终检测出现在网络上的任何新服务器。

I've not worked with this sort of system for quite a few years, but last time we did there was a single server acted as the center point. 我已经很多年没有使用过这种系统了,但是上次我们这样做时只有一台服务器作为中心点。 Everything when it started up broadcasted out to find the central server (retrying at increasing intervals until it found it) and when the central server started up it broadcasted out to find everything - retrying 3 times. 当它启动的所有东西都被广播以找到中央服务器(在增加的时间间隔内重试,直到它找到它),当中央服务器启动它时,它会广播以找到所有内容 - 重试3次。

All communication after that was done by registering with that central server and getting the list of apps etc from there. 之后的所有通信都是通过注册中央服务器并从那里获取应用程序列表等来完成的。 The server essentially acted as a network directory so anything could get a list of anything else on the network by querying it. 服务器本质上充当网络目录,因此任何东西都可以通过查询获得网络上任何其他内容的列表。

You should be doing the following to receive and probably also send broadcast packets (which is what you are asking for): 您应该执行以下操作以接收并可能还发送广播数据包(这是您要求的):

  1. Make sure that network mask is correct 确保网络掩码正确

  2. When you bind the socket, be sure to bind it to INADDR_ANY 绑定套接字时,请确保将其绑定到INADDR_ANY

  3. Set the socket's option to BROADCAST via setsockopt 通过setsockopt将套接字选项设置为BROADCAST

  4. Call the function sendto(..) with sendaddr.sin_addr.s_addr = inet_addr("your_interface_broadcast_address") , or call sento(..) several times for each interface with its broadcast IP address. 使用sendaddr.sin_addr.s_addr = inet_addr("your_interface_broadcast_address")调用函数sendto(..),或者使用广播IP地址为每个接口多次调用sento(..)。

  5. Call the function recvfrom(..), inside a while(..) loop, until you are certain "enough time has passed", usually 1 second should suffice on a LAN network 在一个while(...)循环内调用函数recvfrom(..),直到你确定“已经过了足够的时间”,通常在LAN网络上1秒就足够了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM