COMUNICAÇÃO VIA TCP/IP EM DELPHI UTILIZANDO COMPONENTES TCPCLIENT E TCPSERVER

Uma das tecnologias para implementar a comunicação remota entre um ou vários usuários e um servidor de uma mesma aplicação (programas rodando no mesmo micro, em rede local ou até mesmo via Internet), via Web que o Delphi apresenta utiliza conexão via TCP/IP e os componentes TCPClient  e TCPServer e UDPSocket , da Guia Internet, descendentes de componentes tipo sockets (soquetes, conectores).

Para melhor compreensão, vamos às definições necessárias:

Conexão via TCP/IP - Para transmitir informações de um lado para outro da rede, a Internet se baseia em diversos protocolos. Os principais protocolos, sob os quais todos os demais são construídos são:

TCP ou Transmission Control Protocol;

IP ou Internet Protocol;

Estes dois protocolos são usados em conjunto e conhecidos coletivamente como TCP/IP.

IP significa Internet Protocol ou Protocolo para Internet. É um conjunto de regras para endereçamento de computadores conectados à Internet, necessário para qualquer troca de informações de um computador a outro pela Internet. Cada computador deve ter um endereço único atribuído fixamente (um número identificador permanente, atribuído ao computador quando de sua configuração) ou dinamicamente (o computador recebe um número IP do servidor de Internet a cada conexão. O número pode ser reutilizado). O número é formado por 32 bits, num conjunto de 4 números decimais de 0 a 255 cada, por exemplo: 168.49.200.3. Como os endereços IP numéricos são de difícil memorização, foi desenvolvido o protocolo DNS que traduz ou transforma os endereços numéricos em caracteres legíveis como www.theclub.com.br.

TCP significa Transmission Control Protocol ou Protocolo de Controle de Transmissões. É um conjunto de regras para transmissão de pacotes de dados pela rede que garante que os dados cheguem corretamente ao destino. Usa o protocolo IP para ligar o remetente ao destinatário além de portas (número de 16 bits que identifica um destino dentro do servidor) específicas. Algumas portas têm serviços ou protocolos associados a elas, então quando se cria um programa para troca de informações via TCP/IP, a porta escolhida e que deve ser informada aos componentes TcpClient e TcpServer, deverá ser uma porta que não esteja sendo usada.

Alguns exemplos de portas com protocolos associados:

porta 21: FTP
porta 23: TELNET
porta 25: SMTP (envio de correio)
porta 125: POP3 (recebimento de correio)
porta 80: HTTP (web)

 

Dica importante: além de configurar a porta e o endereço IP também devem ser configurados os roteadores e firewalls no caminho para aceitarem conexões com a porta escolhida (ver em Alterar Configurações do Firewall do Windows).

 

Componentes:

 

"Sockets são abstrações computacionais que mapeiam diretamente uma porta de transporte (TCP ou UDP) e mais um endereço de rede. Com esse conceito, é possível identificar unicamente um aplicativo ou servidor na rede de comunicação IP." (http://pt.wikipedia.org/wiki/Socket).

Socket é, pois, um meio de comunicação que utiliza o protocolo TCP/IP, permitindo que duas ou mais máquinas estabeleçam conexões remotas utilizando uma aplicação cliente e uma servidora. Através dessa tecnologia, um aplicativo instalado em uma máquina cliente pode se comunicar com o mesmo aplicativo instalado em um servidor remoto tanto recebendo como enviando informações (read and write).

Associados a cada um destes componentes socket estão objetos sockets, que representam os pontos finais da conexão. Os componentes socket usam os objetos socket para encapsular as chamadas ao servidor de forma que o aplicativo não precisa se preocupar com os detalhes de estabelecer a conexão ou gerenciar as mensagens.

Para customizar os detalhes da conexão, podem-se usar as propriedades, eventos e métodos dos objetos socket encontrados no Object Inspector.

Existem várias aplicações que utilizam esta tecnologia, como controle de sistemas à distância, trojans, controle de equipamentos à distância, suporte remoto, entre várias outras.

 

O componente TcpClient

É o componente que implementa o lado "cliente" da conexão.

Para ligar um aplicativo a um TCP/IP deve-se adicionar um componente TcpClient a um formulário ou data module . O TcpClient permite que se especifique o  servidor que se quer conectar, o serviço que se quer que o servidor providencie e que a conexão seja completada.

Deve-se configurar as propriedades:

RemotePort - com o número da porta TCP/IP ou nomeando o serviço desejado

RemoteHost -  número IP para identificar o computador remoto. Remote Host é uma string contendo o nome do domínio e o serviço do ponto final remoto da conexão, por exemplo: http://www.wSite.com.

O método Address aceita uma string no formato X.X.X.X. como um endereço IP e o método Host aceita um nome como string.

O método OnConnect é disparado na aplicação cliente assim que o servidor aceita a conexão.

Dicas: escolher uma porta que não esteja sendo usada, permitir ao usuário trocar a porta para o caso de conflitos e configurar roteadores e "firewalls" para aceitarem a conexão na porta escolhida.

 

O componente TcpServer

É o componente que implementa o lado "servidor" da conexão. Permite conexões com múltiplos clientes simultaneamente. Deve ser adicionado a um formulário ou data module na aplicação servidora.

A conexão é feita em tempo de execução chamando o método Open.

Se quiser que seu aplicativo estabeleça a conexão automaticamente assim que iniciado, configure a propriedade Active para True, em tempo de projeto, no Object Inspector ou via código. O componente então fica "escutando" a porta por uma conexão.

Depois de efetuada uma conexão, o método OnAccept pode ser chamado via código. Qualquer inicialização relativa à conexão individual deve ser feita aqui.

Quando o servidor aceita uma conexão, o método OnConnect é disparado na aplicação cliente.

Para enviar informações, utiliza-se o método SendXXX.

 

Propriedade Blocking ou Non-Blocking

A razão para configurar conexões para outras máquinas é poder ler ou escrever informações através dessas conexões. Qual informação se lê ou escreve, ou quando se as lê ou escreve, depende do serviço associado com o conector: bloqueado (blocking) ou não bloqueado (non-blocking).

Modo Não-Bloqueado - o enviar ou receber informações pode ocorrer de forma assíncrona, a qualquer tempo e não impede a execução do restante do código do aplicativo. Roda toda comunicação numa mesma thread.

Modo Bloqueado - usado quando se deseja que o aplicativo espere que o envio ou recebimento de informações seja completado antes de executar a próxima linha de código. Dispara uma nova thread para cada comunicação.

bmBlocking - impede a execução de qualquer código até que uma nova conexão seja estabelecida.

bmThreadBlocking -(para servidores)  cria uma nova execução de código para  todos as conexões de clientes enquanto espera pela informação a ser enviada ou recebida de uma outra conexão.

Há muita controvérsia a respeito das vantagens e desvantagens no uso de blocking e non-blocking, mas é recomendável deixar o valor como stNonBlocking  com exceção de aplicações com servidores de altíssima performance com execução de vários pedidos de conexão simultâneos.


Exemplo de Aplicação Cliente:

Figura1

 

Abaixo temos um exemplo de como implementar uma simples aplicação cliente utilizando sockets TcpCliente.

Funcionalidade: o usuário digitará um texto em um objeto Edit e pressionará um botão; o cliente emitirá um comando para o servidor, que exibirá uma caixa de mensagem com a frase digitada no cliente. Observe que o software cliente estará instalado em uma máquina diferente da servidora.

Inicie uma nova aplicação no Delphi e insira no formulário principal os seguintes componentes:
da Guia Standart:

Adicione 1 GroupBox

 

Altere a propriedade Caption do GroupBox para: Comando Remoto:

Adicione 3 Buttons e coloque dentro do GroupBox

Altere a propriedade Caption do 1º Button para: Conectar.

Altere a propriedade Caption do 2º Button para: Desconectar

Altere a propriedade Caption do 3º Button para: Executar

2 Edits

Altere a propriedade Text dos Edits para: (vazio)

Altere o nome do Edit1 para edthost

Altere o nome do Edit2 para edtsend

Guia Internet:

1 TcpClient

 

No evento OnConnect do TcpClient coloque o seguinte:

procedure TForm1.TcpClient1Connect(Sender: TObject);
begin
     Caption:=’Conectado’;
end;
//Quando o cliente se conectar ao servidor a propriedade caption do Form mudará.

No evento OnDisconnect do TcpClient coloque o seguinte:

procedure TForm1.TcpClient1Disconnect(Sender: TObject);
begin
     Caption:=’Desconectado’;
end;
//Quando o cliente se desconectar do servidor a propriedade caption do form mudará.

No evento OnClick do Button1 (Botão de Conectar) coloque o seguinte código:

procedure TForm1.btnconectarClick(Sender: TObject);
begin
     TcpClient1.RemoteHost:=edthost.Text;
     TcpClient1.RemotePort:=’5000’;
end;
//Quando o usuário clicar em conectar a propriedade RemoteHosts do TCpClient  irá receber o conteúdo do edthostt que, neste caso, será o endereço IP do servidor e a propriedade RemotePort receberá a string 5000, indicando a porta desejada para conexão.

 

No evento OnClick do Button2(Botão de Desconectar) coloque o seguinte código:

procedure TForm1.btndesconectarClick(Sender: TObject);
begin
     TcpClient1.Disconnect;
     if not TcpClient.Connected then
            Caption:=’Cliente – Desconectado’;
end;
//Quando o usuário clicar no botão desconectar ele irá fechar o TcpClient acabando com a conexão e alterar o caption do form.

 

Agora no evento OnClick do Button3(Botão executar)coloque o seguinte código:

procedure TForm1.btnexecutarClick(Sender: TObject);
begin
     TcpClient1.SendIn(edtsend.Text);
end;
//Este botão é o responsável pelo envio de um texto que, no caso, está no edtsend.


Exemplo de aplicação servidora.

Inicie uma nova aplicação no Delphi e insira no formulário principal os seguintes componentes:
 

Figura4

Guia Standart

2 Buttons

Altere a propriedade caption do 1º button para: Ativar

Altere a propriedade caption do 2º button para: Desativar

1 Memo

Guia Internet

1 TcpServer

GuiaIndyMisc

1 IdIPWatch

No evento OnClick do Button1 digite o seguinte código:

 

procedure TForm1.Button1Click(Sender: TObject);
begin
   TcpServer1.LocalPort:='5000';
   TcpServer1.Active:=true;
   if TcpServer1.Active then
      Caption:='Ativo '
   else
      Caption:='Não foi possível a conexão!';
end;
//quando o usuário clicar no botão Ativar, a propriedade LocalPort  do TcpServer receberá a string 5000, indicando o número da porta de conexão; a conexão é aceita através da propriedade Active/true e, uma vez efetuada a conexão, o Caption muda para Ativo, senão mostra a mensagem de que a conexão não foi efetuada.

No evento OnAccept do TcpServer digite o seguinte código:

procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var   s:string;
begin
   s:=ClientSocket.Receiveln;
   Memo1.Lines.Add(s);
end;
//aqui, o TcpServer recebe a mensagem enviada pelo TcpClient e a apresenta no Memo.
No evento OnClick do Button2 digite o seguinte código:
procedure TForm1.Button2Click(Sender: TObject);
begin
   TcpServer1.Close;
   if not TcpServer1.Active then
      Caption:='Não ativo';
end;

Fontes consultadas:

(1) Luciano Ferreira Mendonça (indicação: acesse www.clubedelphi.com.br )
Universidade do Vale do Rio dos Sinos - Unisinos
fmluciano@ig.com.br

(2) http://www.ramosdainformatica.com.br/art_recentes01.php?CDA=30>

(3) Wikipédia - www.wikipedia.com.br

(4) Delphi 7 - módulo Ajuda.

(5) Antonio Spitaleri Neto – Suporte The Club –  www.theclub.com.br



Sobre o Autor

Leonora Golin
Consultora Técnica The Club.

E-mail: suporte@theclub.com.br

The Club - O Maior Clube de programadores do Brasil