Just to share, I was able to achieve the intended result by making a little change in the TcpClient() method, by chunking the received message on the fly as were receiving it. Note that itwas possible to do even with a tinny byte array of only 1024 bytes to hold the incoming data:
package com.valid.insightsiscopam.api
import android.util.Log
import com.MYCOMPANY.MYPRJECT.constants.Constants
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.InputStreamReader
import java.io.PrintWriter
import java.net.Socket
import java.nio.charset.Charset
class TcpClient(private val serverIp: String, private val serverPort: Int) {
// Define timeouts in milliseconds
private val connectionTimeout = 5000 // 5 seconds
private val readTimeout = 5000 // 5 seconds
suspend fun sendMessage(message: String): String {
return withContext(Dispatchers.IO) {
try {
val socket = Socket()
socket.connect(java.net.InetSocketAddress(serverIp, serverPort), connectionTimeout)
// Set the read timeout
socket.soTimeout = readTimeout
// Create output stream to send data to the server
val out = PrintWriter(socket.getOutputStream(), true)
out.println(message) // Send the message
// Create input stream to receive data from the server
val input = socket.getInputStream()
val buffer = ByteArray(1024)
val stringBuilder = StringBuilder()
var bytesRead: Int
// Read data in chunks
while (true)
{
bytesRead = input.read(buffer) // Read bytes into buffer
if (bytesRead == -1) break // End of stream
val chunk = String(buffer, 0, bytesRead, Charset.forName("UTF-8"))
stringBuilder.append(chunk)
Log.d(Constants.LOG_MYPROJECT, "$chunk") // Print each chunk or process it as needed
}
// Close the streams and socket
out.close()
input.close()
socket.close()
// Return the complete response
stringBuilder.toString()
} catch (e: Exception) {
Log.e(Constants.LOG_MYPROJECT, "Error: ${e.message}")
"Error: ${e.message}" // Return the error message
}
}
}
}