Здесь важно то, что любая интенсивная загрузка ЦП или блокировка ввода-вывода (включая ожидание входящих сетевых подключений) происходит в потоке, отдельном от вашего основного потока пользовательского интерфейса.
Если вам просто нужно, чтобы связь по сети продолжала работать, пока ваша активность активна, тогда используйте второй поток в вашей активности. Если вам нужно поддерживать связь по сети даже после того, как ваша активность была прекращена, вам нужно будет воспользоваться услугой.
Имейте в виду, что по умолчанию служба использует один и тот же процесс и поток, как и все остальное в том же приложении (включая действие, предоставляющее ваш пользовательский интерфейс). По этой причине, даже если вы используете службу, вам все равно придется порождать новый поток, чтобы получить желаемый эффект.
AsyncTask используется для выполнения задачи в отдельном потоке, который в конечном итоге завершается и возвращает результат. Если это звучит как ваше приложение, не стесняйтесь использовать его. Но если вы оставляете порт открытым для нескольких запросов (то есть у вас нет единственного возвращаемого значения), использование этого класса будет просто обременительным.