Adobe AIR的 - 如何检测局域网服务器(听一个特定端口) [英] Adobe Air - How to detect LAN servers (listening to a specific port)

查看:213
本文介绍了Adobe AIR的 - 如何检测局域网服务器(听一个特定端口)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道我能检测局域网中的服务器。

I wonder how I can detect LAN servers.

我做了一个客户机/服务器应用程序,这一切工作正常,但你必须手动输入服务器的IP地址。

I made a client/server app and it all works fine but you have to manually enter the IP address of the server.

目前我正在尝试使用的DatagramSocket 客户端/服务器上。 服务器将发送一个包含其IP地址的数据包,所以客户端可以连接到该地址。该数据包发送到本地广播IP(192.168.1.255)端口4444

Currently I'm trying to use a DatagramSocket on the client/server. The server will send a packet containing its IP address so the client can connect to that address. The packet is send it to its local broadcast IP (192.168.1.255) port 4444.

客户端将侦听端口4444然后接收数据包。

The client will listen to port 4444. Then receive the packet.

这工作,如果我是在同一台计算机上(这样是没有错的我的code),而不是当我尝试在另一台计算机上,并尝试连接到我的电脑。

This works if I'm on the same computer (so the is nothing wrong with my code), but not when I try it on another computer and try to connect to my computer.

我没那么熟悉网络,所以我希望有人能向我解释如何正确地做到这一点。

I'm not that familiar with networking so I was hoping someone can explain to me how to do this properly.

此外,在255.255.255.255 AIR广播是不支持:注:将数据发送到广播地址不支持 <一个。 href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/DatagramSocket.html"相对=nofollow>来源

Also, in AIR broadcasting on 255.255.255.255 is not supported: Note: Sending data to a broadcast address is not supported. source

推荐答案

为了实现这一目标,我创建了自己的解决方案(这是不完美的,但唯一的工作方式我能想到的)。

In order to achieve this I've created my own solution (which isn't perfect, but the only working way I could think of).

在服务器端创建一个新的DatagramSocket,将消息发送给每个IP联系地址在一定范围内。

On the server side I create a new DatagramSocket that will send a message to each Ip adress in a certain range.

import flash.utils.setInterval;
import flash.utils.clearInterval;
....

    private const subnetMask:Array = NetworkUtil.getSubnetMask(NetworkUtil.getPrefixLength());
    private const ip:Array = NetworkUtil.getIpAddress().split(".");
    private const ipBroadcastSocket:DatagramSocket = new DatagramSocket();
    private static var _broadcastIp:Boolean;
    private static var intervalId:int;
    ....
    {
    ....
        intervalId = setInterval(broadcastIP, 2000, NetworkUtil.getIpAddress());//broadcast the servers Ip-Address every 2 seconds
    }

    private function broadcastIP(message:String):void
    {
        if(_broadcastIp){
            try
            {
                if(subnetMask[1] != 255 || subnetMask[2] != 255){
                    trace("!!! WARNING: NOT A 'C' CLASS NETWORK !!! (Will not broadcast IP.)");
                    clearInterval(intervalId);
                }
                else
                {
                    var data:ByteArray = new ByteArray();
                    data.writeUTFBytes(message);

                    for(var i4:int = subnetMask[3]; i4 <= 255; i4++){
                        var tempIp:String = ip[0] + "." + ip[1] + "." + ip[2] + "." + (subnetMask[3] == 255 ? ip[3] : i4);
                        if(tempIp != NetworkUtil.getBroadcastIp() && tempIp != NetworkUtil.getSubnetIp(ip, subnetMask)){
                            serverDatagramSocket.send(data, 0, 0, tempIp, port);
                        }
                    }
                }
            }
            catch (error:Error)
            {
                trace(error.message);
            }
        }
    }

然后在客户端,添加其他的DatagramSocket。然后将其绑定到服务器使用相同的端口,并将其设置为接收模式。

Then on the client side, add another DatagramSocket. Then bind it to the same port used by the server and set it to receive mode.

private var ipBroadcastSocket:DatagramSocket = new DatagramSocket();
ipBroadcastSocket.bind(4444);
ipBroadcastSocket.addEventListener(DatagramSocketDataEvent.DATA, dataReceived);
ipBroadcastSocket.receive();

private function dataReceived(e:DatagramSocketDataEvent):void
{
    var data:String = e.data.readUTFBytes(e.data.bytesAvailable);
    trace("Server found with IP: "+ data);
}

下面是我的网络utils的类对于那些要实现这一点:

Here is my network utils class for those that want to implement this:

import flash.net.InterfaceAddress;
import flash.net.NetworkInfo;
import flash.net.NetworkInterface;

public class NetworkUtil
{
    private static var address:InterfaceAddress;

    {//static constructor
        getAddress(); //Get the adress of this host
    }

    public static function getAddress():void
    {
        var interfaceVector:Vector.<NetworkInterface> = NetworkInfo.networkInfo.findInterfaces();
        for each (var networkInt:NetworkInterface in interfaceVector) {
            if (networkInt.active && networkInt.displayName.toLowerCase() != "hamachi") { //Ignore the hamachi interface
                for each (var addresss:InterfaceAddress in networkInt.addresses) {
                    if (addresss.ipVersion == "IPv4") {
                        if(addresss.address != "127.0.0.1"){
                            trace(networkInt.displayName); //Output ipAdress for debugging
                            address = addresss;
                        }
                    }
                }
            }
        }
    }

    public static function getPrefixLength():int
    {
        return address.prefixLength;
    }

    public static function getBroadcastIp():String
    {
        return address.broadcast;
    }

    public static function getIpAddress():String
    {
        return address.address;
    }

    public static function getSubnetIp(currentIp:Array, subnetMask:Array):String
    {           
        for(var i:int; i < 4; i++){
            currentIp[i] = (subnetMask[i] == 255 ? currentIp[i] : 0);
        }

        return currentIp[0] + "." + currentIp[1] + "." + currentIp[2] + "." + currentIp[3];
    }

    public static function getAmountOfHosts(prefixLength:int):int
    {
        return (256 << (24-prefixLength)) -2;
    }

    public static function getSubnetMask(prefixLength:int):Array
    {
        var subnetMask:Array = [];

        for(var i:int = 0; i < 4; i++){
            var subnet:uint = 255;
            if(prefixLength >= 8){
                prefixLength-=8;
            }else{
                subnet = 255 - (255 >> prefixLength);
                prefixLength=0;
            }

            subnetMask[i] = subnet;
        }
        return subnetMask;
    }

    public static function isValidIp(ip:String):Boolean {
        ip = ip.replace( /\s/g, ""); //remove spaces for checking
        var pattern:RegExp = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;

        if(pattern.test(ip)){
            var octets:Array = ip.split(".");
            if (parseInt(String(octets[0])) == 0) {
                return false;
            }
            if (parseInt(String(octets[3])) == 0) {
                return false;
            }
            return true;
        }
        return false;
    }
}

这篇关于Adobe AIR的 - 如何检测局域网服务器(听一个特定端口)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆