<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thiago Melo &#187; Delphi</title>
	<atom:link href="http://thiago.oxente.org/category/programacao/delphi/feed" rel="self" type="application/rss+xml" />
	<link>http://thiago.oxente.org</link>
	<description>Linux, Programação, Redes e Jogos.</description>
	<lastBuildDate>Thu, 04 Feb 2010 18:03:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Criando um Chat no DELPHI utilizando Sockets</title>
		<link>http://thiago.oxente.org/2006/08/16/delphi_chat</link>
		<comments>http://thiago.oxente.org/2006/08/16/delphi_chat#comments</comments>
		<pubDate>Wed, 16 Aug 2006 21:21:55 +0000</pubDate>
		<dc:creator>Thiago Melo</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programação]]></category>

		<guid isPermaLink="false">http://thiago.killermonkeys.net/2006/08/16/delphi_chat/</guid>
		<description><![CDATA[



CRIANDO UM SISTEMA DE CHAT NO DELPHI 
Faculdade de Alagoas (FAL)
  Thiago Nascimento Melo. 3&#186; Per&#237;odo.
Este &#233;  um pequeno tutorial que mostra como criar um simples sistema de CHAT, utilizando o TClientSocket e o TServerSocket, exemplificando como funciona um sistema Cliente/Servidor.
OBS: N&#227;o vou explicar neste tutorial como se coloca componentes, como renomeia e [...]]]></description>
			<content:encoded><![CDATA[<style type="text/css">
<!--
.style1 {
	font-family: Arial, Helvetica, sans-serif;
	font-weight: bold;
	font-size: 18px;
}
.style2 {
	font-family: Verdana, Arial, Helvetica, sans-serif;
	font-size: 12px;
}
.style3 {
	font-size: 14;
	font-weight: bold;
}
.style6 {font-size: 12px}
.code {
	font-family: Arial, Helvetica, sans-serif;
	font-size: 12px;
	color: #006600;
	background-color: #DFFFFF;
	border: 1px solid #000000;
}
.style9 {
	font-size: 14px;
	font-weight: bold;
}
.style11 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; }
.style13 {font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; font-style: italic; }
-->
</style>
<p><body></p>
<p align="center" class="style1">CRIANDO UM SISTEMA DE CHAT NO DELPHI </p>
<p align="left" class="style2 style3">Faculdade de Alagoas (FAL)<br />
  Thiago Nascimento Melo. 3&ordm; Per&iacute;odo.</p>
<p class="style2">Este &eacute;  um pequeno tutorial que mostra como criar um simples sistema de CHAT, utilizando o TClientSocket e o TServerSocket, exemplificando como funciona um sistema Cliente/Servidor.</p>
<p class="style2"><em>OBS: N&atilde;o vou explicar neste tutorial como se coloca componentes, como renomeia e outras coisas b&aacute;sicas de Delphi que o Prof. Luiz Olivio explicou na sala. Este tutorial ensina apenas como utilizar os componentes do Delphi para criar um sistema de Chat (Cliente/Servidor).</em>
</p>
<p class="style2"><strong>Introdu&ccedil;&atilde;o</strong><br />
  <span class="style6">Eu estava procurando no DELPHI algum exemplo de algum sistema que utilizasse a arquitetura cliente/servidor. O mais pr&aacute;tico que encontrei para um melhor entendimento foi os exemplos de CHAT encontrados na pasta DEMO/Internet/Chat do Delphi. (Existe outra pasta chamada NETCHAT, mas n&atilde;o olhei direito o que era).</p>
<p>  Nas pasta CHAT, contem um pequeno projeto de um CHAT, que &eacute; cliente e servidor ao mesmo tempo, que utiliza Winsocket e tamb&eacute;m existe 2 pastas dentro chamadas Client e Server. No conte&uacute;do destas pastas existe um sistema de Chat Cliente/Servidor completo, porem estes utilizam outro componente chamado TcpClient e TcpServer o que eu ainda n&atilde;o estudei direito.</p>
<p>  Quando eu testei os sistemas, reparei que o sistema mais simples (Winsocket) suporta apenas uma comunica&ccedil;&atilde;o Ponto-a-Ponto, isto quer dizer, o servidor suporta apenas 1 conex&atilde;o. Neste caso ficou dif&iacute;cil entender ent&atilde;o resolvi pesquisar na internet e desenvolver outro Chat utilizando Winsocket.</span></p>
<p class="style2"><strong>1&ordf; Etapa</strong><br />
  Para come&ccedil;ar o Chat vamos criar a sua interface, neste caso adicione no programa os seguintes componentes:</p>
<p class="style2">Inserindo:<br />
TMemo =&gt; Coloque o nome como Quadro.<br />
Tmemo =&gt; Com nome de Status.</p>
<p>TGroupBox =&gt; Coloque o nome como C_Comandos<br />
TEdit =&gt; Coloque dentro do TGroupBox (C_Comandos) com o nome de C_Texto<br />
TEdit =&gt; Com nome de Host.<br />
TEdit =&gt; Com nome de Apelido.<br />
TButton =&gt; Com nome de Conectar.</p>
<p>TButton =&gt; Com nome de Servir.<br />
2 Tlabel =&gt; Com caption Servidor e Apelido.<br />
<img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/objetos.jpg" width="474" height="75" align="right"/><br />
Agora adicione os seguintes componentes.<br />
  TclientSocket =&gt; Com nome de S_Cliente.<br />
TserverSocket =&gt; Com nome de S_Server.</p>
<p>(VEJA FIGURA AO LADO) </p>
<p>
Agora renomeie o Form1 para ChatFal. (Clique no Form depois v&aacute; em name e mude).</p>
<p>  Vamos tentar deixar o Object Treeview mais ou menos assim:<br />
  <img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/objtree.jpg" width="187" height="323"/>
</p>
<p class="style2">Pronto agora tente organizar desta forma:</p>
<p>  <img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/tela_xhat.jpg" width="530" height="372"/></p>
<p class="style2"><strong>2&ordf; Etapa </strong></p>
<p class="style2">Bom nesta etapa vamos come&ccedil;ar a programar o chat.</p>
<p class="style2"><span class="style9">a)</span> O primeiro evento que o programa ir&aacute; executar ser&aacute; o TchatFal.FormCreate, clique 2x no formul&aacute;rio, e deixe este procedimento assim:</p>
<div class="code">&nbsp;&nbsp;&nbsp;&nbsp;<br />
  procedure TChatFal.FormCreate(Sender: TObject); {Limpa o quadro}<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quadro.Text := '';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end; 
</div>
<p><span class="style2"><strong>Explica&ccedil;&atilde;o: </strong></span></p>
<p>  <span class="style2">Com isto, assim que o formul&aacute;rio inicie, o conte&uacute;do do componente QUADRO ser&aacute; apagado.<br />
  </span></p>
<p class="style2"><span class="style9">b)</span> O segundo evento a ser programado ser&aacute; do componente C_Texto. Aqui vamos criar uma [i]procedure[/i] para o evento OnKeyDown (Este evento ocorre quando um texto for digitado na Tedit).</p>
<p class="style2">Primeiro se declara a <em>procedure</em>.</p>
<div class="code">
  procedure C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
</div>
</p>
<p class="style2">Depois vamos programar a <em>procedure</em>.</p>
<p class="style2">
<div class="code">
  procedure TChatFal.C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if Key = VK_Return then<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Socket.SendText(C_Texto.Text + '::::' + Apelido.Text);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;C_Texto.Text := '';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;</p>
</div>
<p><span class="style2"><br />
</span></p>
<p><strong>Explica&ccedil;&atilde;o: </strong><br />
Nos criamos uma <em>procedure</em> que utiliza uma vari&aacute;vel &ldquo;Key&rdquo; do tipo Word, e declaramos tamb&eacute;m o uso do Shift (Se n&atilde;o declarar o uso do shift n&atilde;o funciona).</p>
<p><span class="code">&nbsp;if Key = VK_Return then</span> =&gt; Se a tecla digitada for igual ao <strong>[ENTER]</strong> ent&atilde;o execute.</p>
<p><span class="code">S_Cliente.Socket.SendText(C_Texto.Text + '::::' + Apelido.Text);</span> =&gt;  Envia o texto para o servidor no formato <strong>(Mensagem::::Apelido)</strong> este formato ser&aacute; explicado mais na frente.</p>
<p><span class="code">&nbsp;C_Texto.Text := '';</span> =&gt; Limpa o conte&uacute;do da <em>TEdit</em> C_Texto. </p>
<p class="style2"><span class="style9">c)</span> Vamos programar a <em>procedure</em> do terceiro evento. Este ser&aacute; para o bot&atilde;o &ldquo;Conectar&rdquo; onde ao clicar o programa ir&aacute; pegar o conte&uacute;do da <em>Tedit</em> &ldquo;Host&rdquo; e tentar conectar-se.</p>
<p class="style2">Clique 2x em cima do bot&atilde;o Conecta, e deixe da seguinte forma:</p>
<div class="code">
  procedure TChatFal.ConectarClick(Sender: TObject);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if S_Cliente.Active then<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Active := False;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conectar.Caption := 'Conectar';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Host := Host.Text;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Active := True;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
<p>
  <span class="style2"><strong>Explica&ccedil;&atilde;o:</strong> </p>
<p>  <span class="code">if S_Cliente.Active then</span> =&gt; Primeiro verificamos se o <em>TclientSocket</em> esta ativo (isto &eacute; se a conex&atilde;o j&aacute; esta ativa).</p>
<p>  <span class="code">&nbsp;S_Cliente.Active := False;</span> =&gt; Se tiver ativo ele desativa (Desconecta).</p>
<p>  <span class="code">Conectar.Caption := 'Conectar';</span> =&gt; Altera o caption do <em>TButton (Conectar) </em>para 'Conectar'. </p>
<p>  <span class="code">&nbsp;else begin</span> =&gt; Caso a conex&atilde;o j&aacute; esteja desativada, isto &eacute; <em>S_Cliente.Active = False</em> ent&atilde;o ele vai se conectar.</p>
<p>  <span class="code">&nbsp;S_Cliente.Host := Host.Text;</span> =&gt; Pega o conteudo de <em>Host</em> isto &eacute; o endere&ccedil;o IP do servidor, e coloca na propriedade Host do componete S_Cliente.</p>
<p>  <span class="code">S_Cliente.Active := True;</span> =&gt; Ativa a conex&atilde;o. </p>
<p></span></p>
<p class="style2"><strong>3&ordf; Etapa </strong></p>
<p>  Agora vamo programar os eventos do conex&atilde;o do Lado Cliente.</p>
<p class="style2"><strong>Primeiro declare os procedimentos abaixo:</strong></p>
<div class="code">
  procedure S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);</p>
<p>  procedure S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);<br />
  procedure S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br />
  procedure S_ClienteRead(Sender: TObject; Socket: TcustomWinSocket);
  </div>
<p class="style2">Estes s&atilde;o os eventos do componente<em> TclientSocket</em> que colocamos no programas e renomamos para <em>S_Cliente</em>.</p>
<p class="style2">Agora vamo programa-los um por um.</p>
<p class="style2"><strong>Primeiro OnConnect.</strong></p>
<div class="code">
  procedure TChatFal.S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Cliente ::&gt; Conectado a: ' + S_Cliente.Host);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conectar.Caption := 'Desconectar';</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Apelido.Enabled := False;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Socket.SendText('NICK::::' + Apelido.Text);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
<p><span class="style2"><strong>Explica&ccedil;&atilde;o:</strong> </span><br />
<span class="style2">Este evento somente ocorre quando h&aacute; sucesso de conex&atilde;o, isto &eacute; logo ap&oacute;s estabelecer conex&atilde;o com o servidor sem erros.</p>
<p><span class="code">&nbsp;Status.Lines.Add('Cliente ::&gt; Conectado a: ' + S_Cliente.Host);</span> =&gt;  Aqui escrevemos no status <em>Status.Lines.Add</em> uma mensagem informando o cliente que ele teve sucesso na conex&atilde;o.</p>
<p><span class="code">&nbsp;Conectar.Caption := 'Desconectar';</span> =&gt; Muda-se o caption do <em>TButton (Conectar)</em> de 'conecta'r para 'desconectar', pois agora sua fun&ccedil;&atilde;o ser&aacute; encerrar a conex&atilde;o.</p>
<p><span class="code">Apelido.Enabled := False;</span> =&gt; Depois desabilitamos o Tedit do Apelido (Apenas para o cliente n&atilde;o mudar de apelido durante a conex&atilde;o o que n&atilde;o afeta nada caso mude).</p>
<p><span class="code">S_Cliente.Socket.SendText('NICK::::' + Apelido.Text);</span> =&gt; Enviamos para o servidor um Texto seguindo o mesmo formato que a procedure de escrever <em>S_Cliente.Socket.SendText</em>. Repare que desta vez o formato muda um pouco, antes era<strong> (Mensagem::::Apelido)</strong> agora &eacute; <strong>(NICK::::Apelido)</strong>. Isto serve para diferenciar o tipo de mensagem, a primeira &eacute; uma mensagem normal, a segunda informa que voc&ecirc; entrou no servidor. </p>
<p><em>O Tratamento desses formatos fica no lado do servidor que veremos em breve.</em></p>
<p></span></p>
<p class="style2"><strong>Segundo evento &eacute; o OnDisconnect.</strong></p>
<div class="code">
  procedure TChatFal.S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Cliente ::&gt; Desconectado ');</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conectar.Caption := 'Conectar';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Apelido.Enabled := True;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
<p><span class="style2"><strong>Explica&ccedil;&atilde;o:</strong> </p>
<p>Este evento &eacute; o oposto do evento anterior, ele somente &eacute; executado quando a conex&atilde;o &eacute; desfeita. </p>
<p><span class="code">Status.Lines.Add('Cliente ::&gt; Desconectado ');</span> =&gt;  Informamos ao cliente com uma mensagem no status <em>Status.Lines.Add.</p>
<p></em><span class="code">Conectar.Caption := 'Conectar';</span> =&gt; Mudamos o caption do <em>TButton (Conectar)</em>  para &quot;conectar&quot;.</p>
<p><span class="code">Apelido.Enabled := True;</span> =&gt; Habilitamos a <em>TEdit (Apelido).</em> </p>
<p></span></p>
<p class="style2"><strong>Terceiro evento &eacute; o OnError.</strong></p>
<div class="code">
  procedure TChatFal.S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Cliente ::&gt; ERRO ao tentar conectar a: ' + S_Cliente.Host);</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
<p><span class="style2"><strong>Explica&ccedil;&atilde;o:</strong> </span><br />
<br />
<span class="style2">Bastante simples, em caso de erro de conex&atilde;o informa no status a mensagem <span class="code"> ERRO ao tentar conectar a: ' + S_Cliente.Host</span>. </span></p>
<p class="style2"><strong>Quarto e ultimo evento da TclientSocket, OnRead.</strong></p>
<div class="code">
  procedure TChatFal.S_ClienteRead(Sender: TObject; Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Quadro.Lines.Add(Socket.ReceiveText);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
<p><span class="style2"><strong>Explica&ccedil;&atilde;o:</strong> </span><br />
<span class="style2"> Este evento ocorre quando o TClientSocket recebe dados atrav&eacute;s da conex&atilde;o ativa. Como a mensagem j&aacute; vem formatada pelo servidor basta apenas adicionar no quadro </span><span class="code">&nbsp;Quadro.Lines.Add(Socket.ReceiveText);</span> . </p>
<p class="style2"><em>Pronto aqui finalizamos a programa&ccedil;&atilde;o do lado Client do nosso chat.</em></p>
<p class="style2"><strong>EDITANDO AS PROPRIEDADES DO COMPONETE TClientSocket (S_Cliente).</strong> </p>
<p>Agora vamos parar um pouco a programa&ccedil;&atilde;o, e vamos alterar as propriedades do nosso componente TclientSocket. Onde aqui vamos configurar a porta de comunica&ccedil;&atilde;o e tamb&eacute;m vamos colocar os eventos que programamos nos seus devidos lugares.</p>
<p class="style2">Primeiro selecione o &iacute;cone do componente <em>TclientSocket (S_Cliente)</em> no formul&aacute;rio, depois v&aacute; na janela do <em>&ldquo;Object Inspector&rdquo;</em> e em propriedades coloque <strong>Active em FALSE</strong> (Para iniciar desconectado) e em <strong>Port abaixo de Name coloque a seguinte porta (666)</strong> ou outra que voc&ecirc; quiser e que n&atilde;o esteja sendo usada pelo sistema.</p>
<p class="style2">Agora v&aacute; na aba Eventos e configure os eventos como esta abaixo na IMG.</p>
<p class="style2"><img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/client_event.jpg" width="379" height="379"/></p>
<p class="style2">Pronto o lado cliente j&aacute; esta pronto agora vamos programar o lado servidor do nosso chat.</p>
<p class="style2"><strong>4&ordf; Etapa </strong></p>
<p class="style2">Nesta etapa vamos primeiro programar o evento do <em>TButton &quot;Servir&quot;</em> (Eu coloquei a caption deste bot&atilde;o como (Iniciar Servidor).</p>
<p class="style2">Clique 2x no bot&atilde;o para programar o evento.</p>
<div class="code">
  procedure TChatFal.ServirClick(Sender: TObject);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if S_Server.Active = True then<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Server.Active := False;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Servidor ::&gt; Servidor Desligado!');<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Servir.Caption := 'Iniciar Servidor';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Active := False;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Host.Enabled := True;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conectar.Enabled := True;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Server.Active := True;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Servir.Caption := 'Parar Servidor';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Host.Enabled := False;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Conectar.Enabled := False;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Host := '127.0.0.1';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;S_Cliente.Active := True;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;</div>
<p class="style2"><strong>Explica&ccedil;&atilde;o:</strong> <br />
  Primeiro da mesma forma que o bot&atilde;o de conectar primeiro verificamos o estado do servidor. Se ele est&aacute; servindo ou esta parado.</p>
<p>  <span class="code">&nbsp;&nbsp;if S_Server.Active = True then</span> =&gt;   Caso esteja ativo, isto &eacute; caso ele esteja esperando conex&otilde;es na porta configurada, ent&atilde;o vamos desligar. </p>
<p>  <span class="code">S_Server.Active := False;</span> =&gt; Desliga o servidor.</p>
<p>  <span class="code">Status.Lines.Add('Servidor ::&gt; Servidor Desligado!');</span> =&gt; Informa no status que o servidor foi desligado. </p>
<p>  <span class="code">Servir.Caption := 'Iniciar Servidor';</span> =&gt; Muda o caption do <em>TButton (Servir)</em>  para 'iniciar servidor'.</p>
<p>  <span class="code">S_Cliente.Active := False;</span> =&gt; Desativa a conex&atilde;o do cliente. (Ao iniciar o servidor automaticamente o programa se conecta ao servidor). </p>
<p>  <span class="code">&nbsp;Host.Enabled := True;</span> =&gt; Abilita o campo de escolha do IP. </p>
<p>  <span class="code">Conectar.Enabled := True;</span>   =&gt; Abilita o bot&atilde;o de conectar. </p>
<p>  <span class="code">else begin</span>  =&gt; Caso o servidor n&atilde;o esta ativo, ent&atilde;o ative. </p>
<p>  <span class="code">S_Server.Active := True;</span>  =&gt; Ativa o servidor, e neste momento o servidor fica esperando conex&otilde;es na porta configurada. </p>
<p>  <span class="code">Servir.Caption := 'Parar Servidor';</span>  =&gt; Muda o caption do TButton (Servir) para 'parar servidor' pois sua fun&ccedil;&atilde;o agora &eacute; parar.</p>
<p>  <span class="code">Host.Enabled := False;</span>  =&gt; Desativa o campo de escolha do IP (O cliente vai se conectar no localhost). </p>
<p>  <span class="code">&nbsp;Conectar.Enabled := False;</span>  =&gt; Desativa o bot&atilde;o de conectar, pare evitar desconex&atilde;o do cliente com o servidor local. </p>
<p>  <span class="code">&nbsp;S_Cliente.Host := '127.0.0.1';</span>  =&gt; For&ccedil;a o host do S_Cliente para localhost (127.0.0.1). </p>
<p>  <span class="code">&nbsp;S_Cliente.Active := True;</span>  =&gt; Conecta no servidor como cliente. </p>
<p class="style2">O IP '127.0.0.1' Corresponde a pr&oacute;pria maquina, neste caso ao ligar o servidor ele tamb&eacute;m se conecta como cliente e desabilita as op&ccedil;&otilde;es de conex&atilde;o, caso desligue o servidor ele tamb&eacute;m se desconecta.
</p>
<p class="style2"><strong>Agora o passo seguinte e declarar os procedimentos dos eventos do S_Server.</strong></p>
<div class="code">
  procedure S_ServerListen(Sender: TObject; Socket: TCustomWinSocket);<br />
  procedure S_ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);</p>
<p>  procedure S_ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);<br />
  procedure S_ServerClientRead(Sender: TObject; Socket: TcustomWinSocket);
  </div>
<p>
<span class="style2">Os eventos s&atilde;o parecidos com os eventos do S_Cliente com diferen&ccedil;a que n&atilde;o usa o evento OnError e agora existe o evento OnListen. </span></p>
<p class="style2">Vamos aos eventos.</p>
<p class="style2"><strong>Primeiro o evento OnListen.</strong></p>
<div class="code">
  procedure TChatFal.S_ServerListen(Sender: TObject;<br />
  Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Servidor ::&gt; Servidor Ligado!');<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;</p></div>
</p>
<p>  <span class="style11">Explica&ccedil;&atilde;o: </span><span class="style2"><br />
  Este evento ocorre quando o servidor &eacute; ligado, isto &eacute; quando ele come&ccedil;ar a escutar na porta determinada. Quando isto ocorre ele simplesmente escreve no status a mensagem de que o servidor est&aacute; ligado.</span> <span class="code">Status.Lines.Add('Servidor ::&gt; Servidor Ligado!');</span></p>
<p class="style2"><strong>Segundo evento ser&aacute; o OnClientConnect.</strong></p>
<div class="code">
  procedure TChatFal.S_ServerClientConnect(Sender: TObject;<br />
  Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Servidor ::&gt; Usu&aacute;rio Conectado =&gt; '+ Socket.RemoteAddress);</div>
</p>
<p>
&nbsp;&nbsp;&nbsp;&nbsp;  end;</p>
<p>  <span class="style2"><strong>Explica&ccedil;&atilde;o:</strong></p>
<p>  Este evento ocorre quando o servidor recebe uma conex&atilde;o de algum cliente. Quando isto ocorrer vamos escrever no status do servidor uma mensagem informando que um novo usu&aacute;rio se conectou e qual seu IP (Socket.RemoteAddress). </p>
<p>  <span class="code">Status.Lines.Add('Servidor ::&gt; Usu&aacute;rio Conectado =&gt; '+ Socket.RemoteAddress</span>  </span></p>
<p class="style2"><strong>Terceiro evento ser&aacute; o OnClientDisconnect.</strong></p>
<div class="code">
  procedure TChatFal.S_ServerClientDisconnect(Sender: TObject;<br />
  Socket: TCustomWinSocket);</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Servidor ::&gt; Usu&aacute;rio Desconectado =&gt; '+ Socket.RemoteAddress);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;end;
  </div>
</p>
<p>  <span class="style2"> <strong>Explica&ccedil;&atilde;o: </strong><br />
  Este evento ocorre quando o servidor termina uma conex&atilde;o de algum cliente. Quando isto ocorrer vamos escrever no status do servidor uma mensagem informando que o usu&aacute;rio se desconectou e qual seu IP (Socket.RemoteAddress). <br />
  <span class="code">Status.Lines.Add('Servidor ::&gt; Usu&aacute;rio Desconectado =&gt; '+ Socket.RemoteAddress);</span>  </span></p>
<p class="style2"><strong>Quarto e mais importante evento OnClientRead.</strong></p>
<div class="code">
  procedure TChatFal.S_ServerClientRead(Sender: TObject;<br />
  Socket: TCustomWinSocket);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;var texto: array[0..1] of string;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;temptexto: string;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;Index: integer;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;begin</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temptexto := Socket.ReceiveText;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;texto[0] := Copy(temptexto, 1,Pos('::::', temptexto) -1);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;texto[1] := Copy(temptexto, Pos('::::', temptexto) + Length('::::'),Length(temptexto));<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if texto[0] = 'NICK' then {Verifica se a mensagem eh de entrada}<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  </p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WITH S_Server.Socket DO BEGIN {Se a msg for de entrada avisa a todos os clientes quem entrou }<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FOR Index := 0 TO ActiveConnections-1 DO BEGIN<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connections[Index].SendText(texto[1] + ' entrou na sala: ');<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
  </div>
</p>
<p class="style2"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WITH S_Server.Socket DO BEGIN {Se nao for de entrada, ent&atilde;o eh msg normal, no caso passa para todos a msg}<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FOR Index := 0 TO ActiveConnections-1 DO BEGIN<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connections[Index].SendText('(' + texto[1] + ') escreveu: ' + texto[0]);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END;</p>
<p>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status.Lines.Add('Servidor ::&gt; ' + texto[1] + ' (' + Socket.RemoteAddress + ') escreveu: '+ texto[0]);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;</p>
<p class="style2">end;</p>
<p><span class="style2"><br />
</span></p>
<p><strong> Explica&ccedil;&atilde;o </strong></p>
<p>Este evento &eacute; o mais importante do chat, pois &eacute; nele que realmente o chat ir&aacute; funcionar. O evento ocorre quando o servidor recebe dados do cliente, neste caso ele ter&aacute; que receber a mensagem e repassar para todos os clientes conectados (Broadcasting). </p>
<p class="style2">Esta parte foi dif&iacute;cil desenvolver, pois no exemplo que vem no Delphi (WinSocket) ele n&atilde;o envia para todos os usu&aacute;rios a mensagem, ele apenas adiciona na Memo a informa&ccedil;&atilde;o recebida.</p>
<p class="style2">Depois de uma boa pesquisada no <a href="http://www.google.com.br" target="_blank">GOOGLE</a> sobre WinSocket eu achei uma solu&ccedil;&atilde;o funcional.</p>
<p class="style2">Bom vamos passo a passo do c&oacute;digo.</p>
<p class="style2"><span class="code">var texto: array[0..1] of string;</span> =&gt; Este array ser&aacute; necess&aacute;ria para formata&ccedil;&atilde;o dos dados.</p>
<p>  <span class="code">&nbsp;temptexto: string;</span> =&gt; Est&aacute; vari&aacute;vel ser&aacute; necess&aacute;ria para formata&ccedil;&atilde;o dos dados.</p>
<p>  <span class="code">&nbsp;Index: integer;</span> =&gt; Vari&aacute;vel de controle para o loop de broadcast.</p>
<p>  <span class="code">temptexto := Socket.ReceiveText;</span> =&gt; Vari&aacute;vel <em>temptexto</em> recebe os dados enviados pelo cliente <span class="style13">Socket.ReceiveText</span>.</p>
<p>  <span class="code">&nbsp;texto[0] := Copy(temptexto, 1,Pos('::::', temptexto) -1);</span> =&gt; Separa a informa&ccedil;&atilde;o em duas partes, texto[0] pega tudo que estiver antes do separador '::::' (Lembre-se do formato de envio). OBS: Procure no HELP do Delphi explica&ccedil;&otilde;es sobre as fun&ccedil;&otilde;es Pos, Length e Copy. Pois s&atilde;o muito uteis. </p>
<p>  <span class="code">texto[1] := Copy(temptexto, Pos('::::', temptexto) + Length('::::'),Length(temptexto));</span> =&gt; Aqui texto[1] pega tudo que estiver depois do separador '::::'.</p>
<p>  <span class="code">if texto[0] = 'NICK' then</span> =&gt; Se o que estiver antes de '::::' for NICK ent&atilde;o foi mensagem de entrada.</p>
<p>  <span class="code">&nbsp;WITH S_Server.Socket DO BEGIN </span> =&gt; Bom aqui eu estou dizendo que com o Objeto S_Server.Socket Fa&ccedil;a. No help do Delphi tem uma explica&ccedil;&atilde;o sobre 'WITH'.</p>
<p>  <span class="code">&nbsp;FOR Index := 0 TO ActiveConnections-1 DO BEGIN</span>=&gt; Um la&ccedil;o usando FOR, at&eacute; o final das conex&otilde;es. (ActiveConnections vem do objeto S_Server atrav&eacute;s do WITH).</p>
<p>  <span class="code">Connections[Index].SendText(texto[1] + ' entrou na sala: ');</span> =&gt; Vai enviando mensagens para todas as conex&otilde;es da primeira at&eacute; a ultima, informando quem entrou no servidor.</p>
<p>  <span class="code">Else</span> =&gt; Se n&atilde;o for 'NICK' o que vem antes do separador '::::', ent&atilde;o deve ser mensagem.</p>
<p>  <span class="code">WITH S_Server.Socket DO BEGIN </span>=&gt; Denovo WITH.</p>
<p>  <span class="code">FOR Index := 0 TO ActiveConnections-1 DO BEGIN</span> =&gt; La&ccedil;o de 0 at&eacute; o final das conex&otilde;es.</p>
<p>  <span class="code">Connections[Index].SendText('(' + texto[1] + ') escreveu: ' + texto[0]);</span> =&gt; Envia para todas as conex&otilde;es a mensagem enviada.</p>
<p>  <span class="code">Status.Lines.Add('Servidor ::&gt; ' + texto[1] + ' (' + Socket.RemoteAddress + ') escreveu: '+ texto[0]);</span> =&gt; Adiciona no status do servidor uma c&oacute;pia da mensagem.
</p>
<p class="style2">Pronto agora terminamos de programar os eventos do componente S_Server. Agora vamos editar suas propriedades no <em> Object Inspector</em> da mesma forma que configuramos o <em>S_Client.</em></p>
<p>  Deixamos Active = False<br />
  e Port = 666 (Ou a porta que voc&ecirc; usou no <em>S_Client</em>).</p>
<p>  e os eventos (Events)</p>
<p>  <strong>OnClientConnect = S_ServerClientConnect<br />
  OnClientDisconnect = S_ServerClientDisconnect<br />
  OnClientRead = S_ServerClientRead<br />
  OnListen = S_ServerListen</strong></p>
<p class="style2">O resto dos eventos ficam em branco como na imagem abaixo:</p>
<p class="style2"><img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/objserver.jpg" width="190" height="381"/></p>
<p class="style2"><strong>TESTANDO O CHAT</strong> </p>
<p>Pronto salve tudo e compile, agora v&aacute; na pasta em que o programa foi compilado e abra 3 janelas do programa. </p>
<p class="style2">No primeiro coloque o apelido como Administrador e clique em iniciar o Servidor.<br />
  No segundo coloque como usuario1 digite o endere&ccedil;o local (127.0.0.1) e clique em conectar.<br />
  No Terceiro coloque como usuario2 digite o endere&ccedil;o local (127.0.0.1) e clique em conectar.</p>
<p class="style2">Pronto agora teste a comunica&ccedil;&atilde;o entre os 3.</p>
<p><img src="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/xhat_usando.jpg" width="529" height="371"/></p>
<p class="style2">
Bom espero que tenha funcionado seu CHAT, voc&ecirc; pode baixar o c&oacute;digo fonte completo do chat e a vers&atilde;o bin&aacute;ria do mesmo neste link abaixo:</p>
<p class="style2"><a href="http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/c_h_a_t_f_a_l.zip">http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/c_h_a_t_f_a_l.zip</a></p>
<p class="style2">(O nome do arquivo esta separado por _ para evitar de ser bloqueado pelo Proxy da rede da FAL.)</p>
<p align="center" class="style2"><strong>Links de refer&ecirc;ncia usados:</strong><br />
  <a href="http://www.guiadodelphi.com.br%20" target="_blank">http://www.guiadodelphi.com.br  </a><br />
  <a href="http://www.delphi-forum.de%20" target="_blank">http://www.delphi-forum.de  </a></p>
<p></p>
<p>  Este tutorial pode ser reproduzido e publicado livremente, desde que se mantenha os cr&eacute;ditos do autor.<br />
  <em>12 de Mar&ccedil;o de 2005</em>. <br />
  Thiago Melo <br />
  (<a href="mailto:thiago@dolphinconsult.com.br">thiago@dolphinconsult.com.br</a>).   </p>
<p></body></p>
]]></content:encoded>
			<wfw:commentRss>http://thiago.oxente.org/2006/08/16/delphi_chat/feed</wfw:commentRss>
		<slash:comments>118</slash:comments>
		</item>
	</channel>
</rss>
