Search code examples
kotlintcpclient

TCP/IP Client in Kotlin that does not wait forever for server message


I have simple TCP/IP client code in Kotlin below. This code works. The client opens the socket and loops forever, first sending a message to the server, and then waiting forever for a response form the server. I know this code isn’t great, looping forever, keeping the socket connection open etc., but it is just for test purposes right now.

 fun tcp_client() {
    thread {
        val client1 = Socket(SERVER_IP_ADDRESS, SERVER_IP_PORT)
        val output1 = PrintWriter(client1.getOutputStream(), true)
        val input1 = BufferedReader(InputStreamReader(client1.inputStream))

        while (true) {
                output1.println(str_user_text)
                str_rcvd_data = input1.readLine()
        }
    }
    client1.close()
}

The line:

str_rcvd_data = input1.readLine()

waits forever for a server response.

My question: Is it possible to modify this code so that the client does NOT wait forvever for a server response? Something like this:

If (server data received) {
    // process the data
} else {
    // do something else for now and check again in a short while
}

Thanks in advance for any suggestions

Garrett


Solution

  • I eventually worked this out - I am not sure how 'correct' this solution is, but it works for me:

    Connecting to the server....

    My old code would hang if it couldn't connect, because the call to Socket() with the IP address and Port is a Blocking call - i.e.e wait forever:

    val client1 = Socket(SERVER_IP_ADDRESS, SERVER_IP_PORT)
    

    So I replaced the code with this:

    try {
        client1 = Socket()
        client1.connect(InetSocketAddress(SERVER_IP_ADDRESS, SERVER_IP_PORT), 3000)
        output1 = DataOutputStream (client1.getOutputStream())
        input1 = DataInputStream (client1.getInputStream())
    } catch (ex : Exception) {
        // do something
    } finally {
        // do something
    }
    

    This isn't perfect, but it works.

    For reading the data, my old code called readline() which is blocking:

    str_rcvd_data = input1.readLine()
    

    Now, my code first checks if there is any data and then grabs each byte

    iRxDataAvailable = input1.available()
    while (iRxDataAvailable > 0)
    {
        iRxDataAvailable--
        // Take a copy of the received byte
        byRcvdByte = input1.readByte()
        // Do something with this data byte...
    }
    

    Finally, to send data to the server, the data is placed in a byte array, and then:

    output1.write(byArray)