Actionscript 3 AdobeAIR-如何检测LAN服务器(侦听特定端口)
我想知道如何检测局域网服务器 我制作了一个客户端/服务器应用程序,一切正常,但您必须手动输入服务器的IP地址 目前,我正在尝试在客户机/服务器上使用Actionscript 3 AdobeAIR-如何检测LAN服务器(侦听特定端口),actionscript-3,flash,networking,air,udp,Actionscript 3,Flash,Networking,Air,Udp,我想知道如何检测局域网服务器 我制作了一个客户端/服务器应用程序,一切正常,但您必须手动输入服务器的IP地址 目前,我正在尝试在客户机/服务器上使用DatagramSocket。 服务器将发送包含其IP地址的数据包,以便客户端可以连接到该地址。数据包被发送到其本地广播IP(192.168.1.255)端口4444 客户端将侦听端口4444。然后接收数据包 如果我在同一台计算机上(因此我的代码没有问题),但当我在另一台计算机上尝试并尝试连接到我的计算机时,这种方法就不起作用了 我不太熟悉网络,所以
DatagramSocket
。
服务器将发送包含其IP地址的数据包,以便客户端可以连接到该地址。数据包被发送到其本地广播IP(192.168.1.255)端口4444
客户端将侦听端口4444。然后接收数据包
如果我在同一台计算机上(因此我的代码没有问题),但当我在另一台计算机上尝试并尝试连接到我的计算机时,这种方法就不起作用了
我不太熟悉网络,所以我希望有人能向我解释如何正确地做到这一点
另外,不支持255.255.255.255上的空中广播:
注意:不支持向广播地址发送数据。
要查找局域网中的其他计算机,服务器必须发送UDP广播,而AIR不支持。如果服务器必须在空中实现,则可以使用本机扩展(android/ios)或通过执行UDP广播的NativeProcess(桌面)调用系统进程
以下是一些可能有用的链接:
为了实现这一点,我创建了自己的解决方案(这不是完美的,但却是我能想到的唯一可行的方法) 在服务器端,我创建了一个新的DatagramSocket,它将向特定范围内的每个Ip地址发送消息
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);
}
}
}
下面是我的network utils类,适用于希望实现此功能的用户:
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;
}
}
导入flash.net.interfacedAddress;
导入flash.net.NetworkInfo;
导入flash.net.NetworkInterface;
公共类NetworkUtil
{
私有静态var地址:InterfaceAddress;
{//静态构造函数
getAddress();//获取此主机的地址
}
公共静态函数getAddress():void
{
var interfaceVector:Vector.=NetworkInfo.NetworkInfo.findInterfaces();
对于每个(变量networkInt:interfaceVector中的NetworkInterface){
如果(networkInt.active&&networkInt.displayName.toLowerCase()!=“hamachi”){//忽略hamachi接口
对于每个(变量地址:networkInt.addresses中的InterfaceAddress){
如果(addresss.ipVersion==“IPv4”){
如果(地址!=“127.0.0.1”){
跟踪(networkInt.displayName);//输出用于调试的iPAddress
地址=地址;
}
}
}
}
}
}
公共静态函数getPrefixLength():int
{
返回地址。前缀长度;
}
公共静态函数getBroadcastIp():字符串
{
返回地址.广播;
}
公共静态函数getIpAddress():字符串
{
返回地址。地址;
}
公共静态函数getSubnetIp(currentIp:Array,subnetMask:Array):字符串
{
for(变量i:int;i<4;i++){
currentIp[i]=(子网掩码[i]==255?currentIp[i]:0);
}
返回currentIp[0]+“+currentIp[1]+”+currentIp[2]+“+currentIp[3];
}
公共静态函数getAmountOfHosts(前缀长度:int):int
{
返回(256=8){
预桥长度-=8;
}否则{
子网=255-(255>>前缀长度);
预桥长度=0;
}
子网掩码[i]=子网;
}
返回子网掩码;
}
公共静态函数isValidIp(ip:String):布尔值{
ip=ip.replace(//\s/g,“”;//删除空格以进行检查
变量模式:RegExp=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
if(模式测试(ip)){
变量八位字节:数组=ip.split(“.”);
if(parseInt(字符串(八位字节[0]))==0){
返回false;
}
if(parseInt(字符串(八位字节[3]))==0){
返回false;
}
返回true;
}
返回false;
}
}
虽然您可以在Windows系统上使用192.168.0.255,但在MacOS X上会出现异常。相反,您可以在MacOS X上使用D类IP广播。。。224.0.0.1谢谢你让我知道没有其他来源是不可能的。我甚至不确定AIR是否能接收到广播。在我看来,第一个家伙似乎必须用phyton脚本接收广播,该脚本将广播转发到同一台机器上的单播端口,实际的AIR客户端在那里收听。我正在尝试实现这一点。。请原谅我的无知,但你能解释一下子网掩码是如何工作的吗?@user5839是的,当然。我已经实现了这个功能来检查您当前所在的网络类型。如果是A或B网络,发送的数据包数量将过高,结果是无法找到服务器。我已经添加了networkutils类作为我的答案。我用它来获取子网掩码。您可以这样使用它:NetworkUtil.getSubnetMask(NetworkUtil.getPrefixLength())代码>
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;
}
}