Servidores TCP/IP

Um servidor TCP/IP deve realizar duas tarefas básicas:

  1. permanecer em execução aguardando (listening) a chegada de requisições em alguma porta pré-especificada; e

  2. responder à solicitação através de uma conexão estabelecida com o cliente em função da requisição recebida.

Em Java, a classe que permite a criação de servidores com essa funcionalidade é ServerSocket. O principal método desta classe é accept(), que implementa a espera bloqueada por uma solicitação no endereço de porta especificado na construção do objeto. O retorno desse método é um objeto da classe Socket que complementa a conexão com o soquete da aplicação cliente.

Esse exemplo mostra o código para um servidor que responde a qualquer solicitação com uma mensagem fixa, cujo conteúdo é a seqüência de bytes que compõe um endereço URL.

Um dos possíveis problemas na execução de aplicações segundo o modelo cliente-servidor está associado com o tempo de atendimento a uma solicitação pelo servidor. Se o servidor for um processo monolítico, ele estará indisponível para receber novas requisições enquanto a solicitação não for completamente atendida. A solução para este problema depende da possibilidade de se estabelecer um processamento independente para o atendimento de cada solicitação ao servidor, liberando tão cedo quanto possível o servidor para receber novas solicitações.

Tipicamente, por razões de eficiência, um servidor TCP é implementado como um processo multithreaded. Com as facilidades suportadas pela linguagem Java, torna-se atrativo implementar servidores multithreaded, cujo corpo principal de processamento resume-se a um laço eterno para aceitar solicitações na porta especificada e criar um objeto thread para atender à solicitação recebida. Cada thread criada existe exclusivamente durante o tempo necessário para atender à solicitação.