viney
viney
  • 发布:2015-12-24 13:56
  • 更新:2015-12-25 14:35
  • 阅读:3219

【报Bug】android调用系统api实现udp广播不能获取ip地址

分类:Native.js

源代码如下:
1、TODO标记地方不能获取ip地址,其它数据获取正常

(function($) {  
    $.send = function() {  
        if (plus.os.name == "Android") {  
            // import package  
            var DatagramPacket = plus.android.importClass("java.net.DatagramPacket");  
            var DatagramSocket = plus.android.importClass("java.net.DatagramSocket");  
            var InetAddress = plus.android.importClass("java.net.InetAddress");  
            var InterruptedIOException = plus.android.importClass("java.io.InterruptedIOException");  

            // InetAddress  
            var addr = "255.255.255.255",  
                port = 8080, // 60000  
                TTLTime = 5000;  

            var ia = new InetAddress();  
            var address = ia.getByName(addr);  

            // socket  
            var socket = new DatagramSocket();  
            socket.setSoTimeout(TTLTime);  

            var mac = device.Mac();  
            // console.log(mac);  

            var data = tools.StringToUTF8Bytes(mac);  

            var packet = new DatagramPacket(data, data.length, address, port);  

            // 发送数据  
            socket.send(packet);  

            // 接收返回数据  
            var arr = new Array(255);  
            arr = tools.StringToUTF8Bytes(arr.toString());  
            var resPacket = new DatagramPacket(arr, arr.length);  
            var messageReceived = false;  
            while (!messageReceived) {  
                try {  
                    // console.log(tools.BytesToUTF8String(packet.getData()));  
                    socket.receive(resPacket);  
                    var res = tools.BytesToUTF8String(resPacket.getData());  

                    // 返回接收的数据或发送出的数据。   
                    console.log(res);  
                    // 返回发送出的或接收到的数据的长度。  
                    console.log(resPacket.getLength());  
                    // 返回接收或发送此数据报文的机器的 IP 地址。  
                    // TODO:获取不到ip地址???  
                    console.log(resPacket.getAddress());  

                    // 获取偏移量  
                    console.log(resPacket.getOffset());  
                    // console.log(new String(resPacket.getData(), resPacket.getOffset(), resPacket.getLength()));  

                    // 返回接收或发送该数据报文的远程主机端口号  
                    console.log(resPacket.getPort());  
                } catch (InterruptedIOException) {  
                    // 当receive不到信息或者receive时间超时捕获异常  
                    console.log("catch");  
                    messageReceived = true;  
                    // 关闭数据报   
                    socket.close();  
                }  
            }  
        } else {  
            plus.nativeUI.toast("不支持的版本: " + plus.os.name);  
        }  
    };  

    document.addEventListener("plusready", function() {  
        console.log("当前页面URL: " + plus.webview.currentWebview().getURL());  

        $.send();  
    }, false);  
})(window.udp = {});
2015-12-24 13:56 负责人:无 分享
已邀请:
viney

viney (作者) - app的春天来了

提供NodeJS服务端代码
1、先启动服务端
2、直接跑上面的程序就可以

var dgram = require( "dgram" );  

var server = dgram.createSocket("udp4", function(msg, info){  
    console.log( info.address + ':' + info.port + ' - ' + msg );  

    var res = 'viney';  
    server.send( res, 0, res.length, info.port, info.address ); // added missing bracket  
});  

server.bind(8080);
Android_磊子

Android_磊子

参考下http://ask.dcloud.net.cn/question/13494不知道有没有帮助对你。

  • viney (作者)

    没有帮助,现在我的疑问是,调用没有获得数据。

    // TODO:获取不到ip地址???

    console.log(resPacket.getAddress());


    // 返回接收或发送该数据报文的远程主机端口号

    console.log(resPacket.getPort()); //这个能获取数据

    2015-12-24 14:55

viney

viney (作者) - app的春天来了

附上java原生代码:
client.java

package client;  

import java.io.IOException;  
import java.io.InterruptedIOException;  
import java.net.DatagramPacket;  
import java.net.DatagramSocket;  
import java.net.InetAddress;  

public class Client {  
    private static final int TIMEOUT = 5000; // 设置接收数据的超时时间  
    private static final int MAXNUM = 5; // 设置重发数据的最多次数  

    public static void main(String args[]) throws IOException {  
        String str_send = "Hello UDPserver";  
        byte[] buf = new byte[1024];  
        DatagramSocket ds = new DatagramSocket();  
        InetAddress loc = InetAddress.getByName("255.255.255.255");   
        // 定义用来发送数据的DatagramPacket实例  
        DatagramPacket dp_send = new DatagramPacket(str_send.getBytes(),  
                str_send.length(), loc, 8080);  
        // 定义用来接收数据的DatagramPacket实例  
        DatagramPacket dp_receive = new DatagramPacket(buf, 1024);  
        ds.setSoTimeout(TIMEOUT); // 设置接收数据时阻塞的最长时间  
        int tries = 0; // 重发数据的次数  
        boolean receivedResponse = false; // 是否接收到数据的标志位  
        // 直到接收到数据,或者重发次数达到预定值,则退出循环  
        while (!receivedResponse && tries < MAXNUM) {  
            // 发送数据  
            ds.send(dp_send);  
            try {  
                // 接收从服务端发送回来的数据  
                ds.receive(dp_receive);  
                // 如果接收到数据。则将receivedResponse标志位改为true,从而退出循环  
                receivedResponse = true;  
            } catch (InterruptedIOException e) {  
                // 如果接收数据时阻塞超时,重发并减少一次重发的次数  
                tries += 1;  
                System.out.println("Time out," + (MAXNUM - tries)  
                        + " more tries...");  
            }  
        }  
        if (receivedResponse) {  
            // 如果收到数据,则打印出来  
            System.out.println("client received data from server:");  
            String str_receive = new String(dp_receive.getData(), 0,  
                    dp_receive.getLength())  
                    + " from "  
                    + dp_receive.getAddress().getHostAddress() // 可以获取IP  
                    + ":"  
                    + dp_receive.getPort();  
            System.out.println(str_receive);  
            // 由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数,  
            // 所以这里要将dp_receive的内部消息长度重新置为1024  
            dp_receive.setLength(1024);  
        } else {  
            // 如果重发MAXNUM次数据后,仍未获得服务器发送回来的数据,则打印如下信息  
            System.out.println("No response -- give up.");  
        }  
        ds.close();  
    }  
}

server.java

package server;  

import java.io.IOException;  
import java.net.DatagramPacket;  
import java.net.DatagramSocket;  

public class Server {  
    public static void main(String[] args) throws IOException {  
        String str_send = "Hello UDPclient";  
        byte[] buf = new byte[1024];  
        DatagramSocket ds = new DatagramSocket(8080);  
        // 接收从客户端发送过来的数据  
        DatagramPacket dp_receive = new DatagramPacket(buf, 1024);  
        System.out  
                .println("server is on,waiting for client to send data......");  
        boolean f = true;  
        while (f) {  
            // 服务器端接收来自客户端的数据  
            ds.receive(dp_receive);  
            System.out.println("server received data from client:");  
            String str_receive = new String(dp_receive.getData(), 0,  
                    dp_receive.getLength())  
                    + " from "  
                    + dp_receive.getAddress().getHostAddress()  
                    + ":"  
                    + dp_receive.getPort();  
            System.out.println(str_receive);  
            DatagramPacket dp_send = new DatagramPacket(str_send.getBytes(),  
                    str_send.length(),dp_receive.getAddress(),dp_receive.getPort());  
            ds.send(dp_send);  
            // 由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数,  
            // 所以这里要将dp_receive的内部消息长度重新置为1024  
            dp_receive.setLength(1024);  
        }  
        ds.close();  
    }  
}

java原生代码getAddress().getHostAddress()方法获取数据正常,native.js返回Uncaught TypeError: Object #<h> has no method 'getHostAddress'异常。

  • Android_磊子

    这样的特定需求,需要自己先进行android原生层技术实现,在测试成功后转化NJS过程中出现问题,我们可以协助解决。

    2015-12-25 11:01

viney

viney (作者) - app的春天来了

问题已经解决:

不是bug
var serverAddress = resPacket.getAddress();
plus.android.importClass(serverAddress);
console.log(serverAddress.getHostAddress());

该问题目前已经被锁定, 无法添加新回复