0

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

garrettb
  • 139
  • 11
  • 1
    The keyword you're looking for is 'non-blocking'. [Does the answer here help](https://stackoverflow.com/q/3895461/4161471)? You can also try finding coroutines-based socket implementations, e.g. https://github.com/TheEvilRoot/async-coroutines-socket. – aSemy Jun 02 '22 at 17:10

1 Answers1

0

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)
garrettb
  • 139
  • 11