هل البث المتعدد مكسور لنظام Android 2.0.1 (حاليا على Droid) أو أنا أفتقد شيئا؟

StackOverflow https://stackoverflow.com/questions/2414453

سؤال

يعمل هذا الرمز تماما في Ubuntu و Windows و Mac OS X. وهو يعمل أيضا بشكل جيد مع Nexus One يعمل بنظام Android 2.1.1.

أبدأ في إرسال وتستمع إلى مخططات مخططات البيانات المتعددة، وجميع أجهزة الكمبيوتر و Nexus One يرى بعضها البعض تماما. ثم انا تشغيل نفس الرمز على الروبوت (البرامج الثابتة 2.0.1)، و سيحصل الجميع على الحزم المرسلة بواسطة الروبوت، لكن الروبوت سيستمع إلا لحزمه الخاصة.

هذا ال run() طريقة مؤشر ترابط تستمع باستمرار على مجموعة متعددة الإرسال المتعدد للحزم الواردة المرسلة إلى تلك المجموعة.

أقوم بتشغيل اختباراتي على شبكة محلية حيث تم تمكين دعم متعدد الالتزامات في جهاز التوجيه. هدفي هو أن يكون لديك أجهزة تلبي بعضها البعض لأنها تأتي عبر الإنترنت من خلال حزم البث إلى مجموعة متعددة.

public void run() {
    byte[] buffer = new byte[65535];
    DatagramPacket dp = new DatagramPacket(buffer, buffer.length);

    try {
        MulticastSocket ms = new MulticastSocket(_port);
        ms.setNetworkInterface(_ni); //non loopback network interface passed
        ms.joinGroup(_ia); //the multicast address, currently 224.0.1.16
        Log.v(TAG,"Joined Group " + _ia);

        while (true) {
            ms.receive(dp);
            String s = new String(dp.getData(),0,dp.getLength());
            Log.v(TAG,"Received Package on "+ _ni.getName() +": " + s);
            Message m = new Message();
            Bundle b = new Bundle();
            b.putString("event", "Listener ("+_ni.getName()+"): \"" + s + "\"");
            m.setData(b);
            dispatchMessage(m); //send to ui thread
        }
    } catch (SocketException se) {
        System.err.println(se);
    } catch (IOException ie) {
        System.err.println(ie);
    }
}

هذا هو الرمز الذي يرسل مخطط بيانات البث المتعدد من كل واجهة شبكة صالحة متوفرة (هذه ليست واجهة الاسترجاع).

public void sendPing() {
    MulticastSocket ms = null;
    try {
        ms = new MulticastSocket(_port);
        ms.setTimeToLive(TTL_GLOBAL);

        List<NetworkInterface> interfaces = getMulticastNonLoopbackNetworkInterfaces();
        for (NetworkInterface iface : interfaces) {
            //skip loopback
            if (iface.getName().equals("lo"))
                continue;
            ms.setNetworkInterface(iface);
            _buffer = ("FW-"+ _name +" PING ("+iface.getName()+":"+iface.getInetAddresses().nextElement()+")").getBytes();
            DatagramPacket dp = new DatagramPacket(_buffer, _buffer.length,_ia,_port);
            ms.send(dp);
            Log.v(TAG,"Announcer: Sent packet - " + new String(_buffer) + " from " + iface.getDisplayName());
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e2) {
        e2.printStackTrace();
    }
}

تحديث (2 أبريل 2010)لقد وجدت طريقة للحصول على واجهة شبكة الروبوت للتواصل باستخدام البث المتعدد: wifimanager.multicastlock..

MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere");
_wifiMulticastLock.acquire();

ثم عندما تنتهي ...

if (_wifiMulticastLock != null && _wifiMulticastLock.isHeld())
    _wifiMulticastLock.release();

بعد أن قمت بذلك، بدأ الروبوت إرسال واستقبال مخططات بيانات UDP على مجموعة متعددة.

تحديث Jul 6-2010

لكل طلب، إليك الرمز الحالي الخاص بي، توجد الطريقة التالية على فئة مجردة يمكن استخدامها لكل من أجهزة الاستقبال البث والإرسال المتعدد.

public void run() {
    onInit();
    try {
        byte[] data = new byte[65535];
        while (isProcessing()) {
            try {
                DatagramPacket receivedDatagram = new DatagramPacket(data, data.length);
                _socket.receive(receivedDatagram);
                onDatagramReceived(receivedDatagram);
                data = new byte[65535]; // This pattern is for saving memory allocation.
            } catch (InterruptedIOException e) {
                if (!isProcessing())
                    break;
            }
        } // while

    } catch (Exception e) {
        Log.e(TAG, e.getMessage(), e);
    } finally {
        onStop();
        _socket.close();
        _socket.disconnect();
    }
}

يجب أن تنفذ فئات التمديد الخاصة بك onInit() و onDatagramReceived()

ل البث المتعدد المتلقي، onInit() يبدو شيئا مثله:

_socket = new MulticastSocket(PORT_MULTICAST);
InetAddress groupAddress = InetAddress.getByAddress(MULTICAST_GROUP_ADDRESS); 
InetAddress groupInetAddress = FrostWireUtils.fastResolveAddress(groupAddress); //reflection hack to not resolve ips
try {
    _socket.setSoTimeout(500);
    _socket.setTimeToLive(MULTICAST_TTL_GLOBAL);
    _socket.setReuseAddress(true);
    _socket.setNetworkInterface(
        WifiUtils.getWifiNetworkInterface());
    _socket.joinGroup(groupInetAddress);
    WifiUtils.lockMulticast();
} catch (Exception e) {
    Log.e(TAG, e.getMessage(), e);
}
هل كانت مفيدة؟

المحلول

لقد قمت بتنفيذ اختبار آخر، هذه المرة باستخدام UDP إذاعةوبعد إنها تعمل.

خاتمة: إلى حد معرفتي موتورولا الروبوت الهواتف على البرامج الثابتة 2.0.1 لا تدعم البث المتعدد، ولكن يمكنك دائما استخدام Datagrapraphackets العادية على عنوان البث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top