Вы можете использовать диспетчер Dispatchers.IO
для работы с сокетами из сопрограмм так же, как вы делаете это из потоков - сокеты блокируют ввод / вывод, поэтому каждый сокет занимает целый поток, и этот диспетчер может запускать много потоков.
Также есть некоторые неблокирующие библиотеки ввода / вывода для Java, и вы можете найти адаптеры от них для Kotlin Coroutines API (например, вы можете использовать этот прокси между Netty и Coroutines ).