【问题标题】:How to use socket in Android with Kotlin如何通过 Kotlin 在 Android 中使用套接字
【发布时间】:2021-06-18 19:10:01
【问题描述】:

我想在 Android 中使用 Kotlin 实现一些目标:

如果我单击应用程序上的按钮,应用程序会向 TCP 服务器(我用 python 编写)发送一个字。服务器将返回另一个单词,应用程序将显示一条 toast 消息。

这是我到目前为止所做的,我可以弄清楚发送部分,但我无法让它继续监听套接字以接收来自服务器的消息。

我正在尝试使用协程,但是在网上找到所有资源后,这是我能得到的最好的。

另外,我不确定我是否以正确的方式设置 IP 地址。

提前感谢您的帮助!

'''

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

    val sendBtn = findViewById<Button>(R.id.sendBtn )
    val ipBtn = findViewById<Button>(R.id.ipBtn)
    val ipInput = findViewById<TextView>(R.id.ipInput)

    var ipAddress: String = "192.168.0.101"

    // Below is my attempt to keep listening to the socket, if commented, the sending would work. 
    // My guess is the IO thread is caught in the while loop so the other coroutines cannot use 
    // IO thread to send to the server.
    CoroutineScope(IO).launch{
        val socket = Socket(ipAddress, 9999)
        var text = ""
        while (true) {
            text = BufferedReader(InputStreamReader(socket.inputStream)).readLine()
            // if text is not null
            // Toast.makeText(this@MainActivity, "Set IP", Toast.LENGTH_SHORT).show()
        }
    }

    suspend fun sendMessage(message:String){
        val socket = Socket(ipAddress, 9999)
        socket.outputStream.write(message.toByteArray())
        socket.close()
    }

    ipBtn.setOnClickListener {
        Toast.makeText(this@MainActivity, "Set IP", Toast.LENGTH_SHORT).show()
        ipAddress = ipInput.text.toString()
    }

    sendBtn .setOnClickListener {
        CoroutineScope(IO).launch {
            Log.d("TAG", "message")
            sendMessage("record")
        }
    }

'''

【问题讨论】:

  • 解决方案可能是使用线程。这是一个很好的(Java)示例:Sending and Receiving Data with Sockets in android
  • @paulsm4 感谢您的建议。我了解到,对于互联网通信,建议使用协程(例如从 API 获取数据)。你能解释一下为什么在我的情况下线程比协程更受欢迎吗?

标签: android kotlin tcp socket.io kotlin-coroutines


【解决方案1】:

要从 P2P Fist 发送数据,我们需要一个 Server 和 Client 。在这里,Socket 充当了通过网络发送和接收数据的端点。

  1. 像这样创建一个服务器类
 class ServerClass() :Thread(){
       
        lateinit var serverSocket:ServerSocket
        lateinit var inputStream: InputStream
        lateinit var  outputStream: OutputStream
        lateinit var socket: Socket



        override fun run() {
            try {
                serverSocket = ServerSocket(8888)
                socket = serverSocket.accept()
                inputStream =socket.getInputStream()
                outputStream = socket.getOutputStream()
            }catch (ex:IOException){
                ex.printStackTrace()
            }

            val executors = Executors.newSingleThreadExecutor()
            val handler = Handler(Looper.getMainLooper())
            executors.execute(Runnable{
                kotlin.run {
                    val buffer = ByteArray(1024)
                    var byte:Int
                    while (true){
                        try {
                            byte =  inputStream.read(buffer)
                            if(byte > 0){
                                var finalByte = byte
                                handler.post(Runnable{
                                    kotlin.run {
                                        var tmpMeassage = String(buffer,0,finalByte)
                                      
                                        Log.i("Server class","$tmpMeassage")
                                    }
                                })

                            }
                        }catch (ex:IOException){
                            ex.printStackTrace()
                        }
                    }
                }
            })
        }

        fun write(byteArray: ByteArray){
            try {
                Log.i("Server write","$byteArray sending")
                outputStream.write(byteArray)
            }catch (ex:IOException){
                ex.printStackTrace()
            }
        }
    }
  1. 在我们需要传递主机地址的地方创建一个客户端类
class ClientClass(hostAddress: InetAddress): Thread() {
        
         var hostAddress: String = hostAddress.hostAddress
         lateinit var inputStream: InputStream
         lateinit var outputStream: OutputStream
         lateinit var socket: Socket

          fun write(byteArray: ByteArray){
              try {
                  outputStream.write(byteArray)
              }catch (ex:IOException){
                  ex.printStackTrace()
              }
          }

         override fun run() {
             try {
                 socket = Socket()
                 socket.connect(InetSocketAddress(hostAddress,8888),500)
                 inputStream = socket.getInputStream()
                 outputStream = socket.getOutputStream()
             }catch (ex:IOException){
                 ex.printStackTrace()
             }
             val executor = Executors.newSingleThreadExecutor()
             var handler =Handler(Looper.getMainLooper())

             executor.execute(kotlinx.coroutines.Runnable {
                 kotlin.run {
                     val buffer =ByteArray(1024)
                     var byte:Int
                     while (true){
                         try{
                             byte = inputStream.read(buffer)
                             if(byte>0){
                                 val finalBytes = byte
                        handler.post(Runnable{
                                     kotlin.run {
                                         val tmpMeassage = String(buffer,0,finalBytes)
                                        
                                         Log.i("client class", tmpMeassage)
                                     }
                                 })
                             }
                         }catch (ex:IOException){
                             ex.printStackTrace()
                         }
                     }
                 }
             })
         }

     }

确保服务器和客户端端口应该相同,这是双向通信,我们可以在双方传输数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多