Como a conexão via socket no Android é bloqueante, é necessário realizá-la de maneira assíncrona em relação ao fluxo principal, para que o usuário não tenha uma sensação de que o aplicativo travou. Para realizar esse tipo de operação de uma maneira elegante, utilizamos a classe AsyncTask. Essa classe possui um método chamado doInBackground que é responsável por realizar operações concorrentemente com o fluxo principal.
Com isso em mente, criei uma pequena classe responsável por enviar e receber dados via socket.