繁体   English   中英

如何在 Android 和 Kotlin 中使用套接字

[英]How to use socket in Android with Kotlin

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

如果我单击应用程序上的按钮,应用程序会向 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")
        }
    }

'''

要从 P2P Fist 发送数据,我们需要服务器和客户端。 在这里,Socket 充当通过网络发送和接收数据的端点。

  1. 像这样创建服务器 Class
 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 我们需要传递主机地址
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()
                         }
                     }
                 }
             })
         }

     }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM