广播与组播

组播

将同一网络段的设备进行逻辑上的分组。如设定一个组播地址,所有进入该地址的设备是同一个组。任意一个设备向该组发送消息即为组播。

广播

将消息发送给局域网中的每一个设备即为广播。

组播与广播最大的不同在于发送消息的地址不同。

代码示例:

发送端

fun sendMultiBroadcast() {
        if (multicastLock?.isHeld!!) {
            var multicastSocket = MulticastSocket(8600)
            var address = InetAddress.getByName(IP_ADDRESS)
            if (!address.isMulticastAddress) {
                Log.d(TAG, "该地址不是组播地址")
            }
            multicastSocket.joinGroup(address)

            var datagramPacket: DatagramPacket?

            val buf = "hah  i  changed already".toByteArray()
            datagramPacket = DatagramPacket(buf, buf.size, address, 8600)       // 本地的socket端口为8600,所以该socket也可以接收来自自已的消息

            while (true) {
                multicastSocket.send(datagramPacket)    // 在发送时候如果切换网络,则报java.io.IOException: Network is unreachable错误,注意
                Thread.sleep(2000)
                Log.i(TAG, "发送消息到8600端口")
            }

            multicastSocket.leaveGroup(address)
            multicastSocket.close()
        }
    }

有的网络资料显示,android默认不接收组播消息,需要手动打开。如下代码所示:

var wifiManager: WifiManager? = null
    var multicastLock: WifiManager.MulticastLock? = null

    /**
     * 获取multicast锁,网络资料表明android为了节约电量,默认不接收组播消息。
     *
     * 但经过实际demo运行显示,屏蔽该代码,一台三星和一台华为平板之间也是可以正常通信的。
     */
    private fun openMulticastLock() {
        wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        multicastLock = wifiManager?.createMulticastLock("multicast.test")
        multicastLock?.acquire()
    }

接收端代码如下:

fun sendMultiBroadcast() {
        if (multicastLock?.isHeld!!) {
            var multicastSocket = MulticastSocket(8600)
            multicastSocket.timeToLive = 254
            var address = InetAddress.getByName(IP_ADDRESS)
            if (!address.isMulticastAddress) {
                Log.d(TAG, "该地址不是组播地址")
            }
            multicastSocket.joinGroup(address)
            Log.i(TAG, "加入组播")

            val rev = ByteArray(512)
            var revPacket = DatagramPacket(rev, rev.size)
            try {
                multicastSocket.receive(revPacket)
            } catch (e: Exception) {
                Log.e(TAG, "接收错误", e)
            }

            Log.i(TAG, "data is " + String(revPacket.data))
            mMainHandler.post {
                tv_msg.text = String(revPacket.data) + revPacket.address.hostAddress
            }

            multicastSocket.leaveGroup(address)
            multicastSocket.close()
        }
    }

    companion object {
        const val TAG = "sx"
        const val IP_ADDRESS = "239.0.0.1"
        const val SEND_ID = 0x0001
    }

其中,发送端和接收端的ip地址和端口要一致。

两台设备如果同在一个局域网内可以通过此种方法通信。

猜你喜欢

转载自blog.csdn.net/honeysx/article/details/86008633
今日推荐