如何在 Kotlin 上进行持续 UDP 数据监听

6
我正在寻找一种方法,以便每次收到UDP数据包时都能触发名为receiveUDP的函数。在Kotlin中我该如何做呢?以下是我目前正在工作的简单聊天代码:
它使用01个editText用于用户输入,01个textView用于显示接收到的数据包,并且一个按钮用于发送用户输入。
package com.e.udpchat1

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.StrictMode
import android.view.View
import android.widget.EditText
import android.widget.TextView
import java.io.IOException
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress


class SoftOptions {
    var RemoteHost: String = "192.168.1.255"
    var RemotePort: Int = 6454

    constructor()
    init{}
}

// Global
val Settings = SoftOptions()

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Where should I call?
        // var Buffer = receiveUDP(1500)
        // so that it constantly listen to incoming UDP packets
    }

    fun clickButtonSend(view: View) {
        // Do something in response to button
        // Send editText1 Text thru UDP.
        val editText = findViewById<EditText>(R.id.editText1)
        var message = editText.text.toString()
        sendUDP(message)
        // Add text to textView1.
        val textView = findViewById<TextView>(R.id.textView1)
        var chat = textView.text.toString()
        textView.setText(chat + message + "\n")
        // Clear editText1 after all sent.
        editText.setText("")// Clear Input text.
    }

    fun sendUDP(messageStr: String) {
        // Hack Prevent crash (sending should be done using an async task)
        val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
        StrictMode.setThreadPolicy(policy)
        try {
            //Open a port to send the package
            val socket = DatagramSocket()
            socket.broadcast = true
            val sendData = messageStr.toByteArray()
            val sendPacket = DatagramPacket(sendData, sendData.size, InetAddress.getByName(Settings.RemoteHost), Settings.RemotePort)
            socket.send(sendPacket)
            println("fun sendBroadcast: packet sent to: " + InetAddress.getByName(Settings.RemoteHost) + ":" + Settings.RemotePort)
        } catch (e: IOException) {
    //            Log.e(FragmentActivity.TAG, "IOException: " + e.message)
        }
    }

    fun receiveUDP( size: Int): ByteArray {
        val ret = ByteArray(size)
        var socket: DatagramSocket? = null
        try {
            //Keep a socket open to listen to all the UDP trafic that is destined for this port
            socket = DatagramSocket(Settings.RemotePort, InetAddress.getByName(Settings.RemoteHost))
            socket.broadcast = true
            val Buffer = ByteArray(1500)
            val packet = DatagramPacket(Buffer, Buffer.size)
            socket.receive(packet)

            // Add text to textView1.
            val textView = findViewById<TextView>(R.id.textView1)
            val chat = textView.text.toString()
            textView.setText(chat + packet + "\n")

        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            socket?.close()
        }
        return ret
    }
}

我希望在textView1中看到每个接收到的数据包。
1个回答

5

我发现了可运行对象(Runnables)并使用它们来持续检查数据是否到达。

package com.e.udpchat1

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.StrictMode
import android.view.View
import android.widget.EditText
import android.widget.TextView
import java.io.IOException
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress


class SoftOptions {
    var RemoteHost: String = "192.168.1.255"
    var RemotePort: Int = 6454

    constructor()
    init{}
}


// Global
val Settings = SoftOptions()


open class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        println("Create Runnable example.")
        val threadWithRunnable = Thread(udp_DataArrival())
        threadWithRunnable.start()

        // Add text to textView1.
            val textView = findViewById<TextView>(R.id.textView1)
            textView.setText("Hello World from main!\n")

        println("MainActivity onCreate success.")
    }

    fun clickButtonSend(view: View) {
        // Do something in response to button
        // Send editText1 Text thru UDP.
        val editText = findViewById<EditText>(R.id.editText1)
        var message = editText.text.toString()
        sendUDP(message)
        // Add text to textView1.
//        val textView = findViewById<TextView>(R.id.textView1)
//        var chat = textView.text.toString()
//        textView.setText(chat + message + "\n")
        // Clear editText1 after all sent.
        editText.setText("")// Clear Input text.
    }

    fun sendUDP(messageStr: String) {
        // Hack Prevent crash (sending should be done using an async task)
        val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
        StrictMode.setThreadPolicy(policy)
        try {
            //Open a port to send the package
            val socket = DatagramSocket()
            socket.broadcast = true
            val sendData = messageStr.toByteArray()
            val sendPacket = DatagramPacket(sendData, sendData.size, InetAddress.getByName(Settings.RemoteHost), Settings.RemotePort)
            socket.send(sendPacket)
            println("fun sendBroadcast: packet sent to: " + InetAddress.getByName(Settings.RemoteHost) + ":" + Settings.RemotePort)
        } catch (e: IOException) {
    //            Log.e(FragmentActivity.TAG, "IOException: " + e.message)
        }
    }

    open fun receiveUDP() {
        val buffer = ByteArray(2048)
        var socket: DatagramSocket? = null
        try {
            //Keep a socket open to listen to all the UDP trafic that is destined for this port
            socket = DatagramSocket(Settings.RemotePort, InetAddress.getByName(Settings.RemoteHost))
            socket.broadcast = true
            val packet = DatagramPacket(buffer, buffer.size)
            socket.receive(packet)
            println("open fun receiveUDP packet received = " + packet.data)

        } catch (e: Exception) {
            println("open fun receiveUDP catch exception." + e.toString())
            e.printStackTrace()
        } finally {
            socket?.close()
        }
    }

}



class udp_DataArrival: Runnable, MainActivity() {
    public override fun run() {
        println("${Thread.currentThread()} Runnable Thread Started.")
        while (true){
            receiveUDP()
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接