Criando um Chat no DELPHI utilizando Sockets

16 agosto, 2006

CRIANDO UM SISTEMA DE CHAT NO DELPHI

Faculdade de Alagoas (FAL)
Thiago Nascimento Melo. 3º Período.

Este é 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ão vou explicar neste tutorial como se coloca componentes, como renomeia e outras coisas bá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).

Introdução
Eu estava procurando no DELPHI algum exemplo de algum sistema que utilizasse a arquitetura cliente/servidor. O mais prá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ão olhei direito o que era).

Nas pasta CHAT, contem um pequeno projeto de um CHAT, que é cliente e servidor ao mesmo tempo, que utiliza Winsocket e também existe 2 pastas dentro chamadas Client e Server. No conteú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ão estudei direito.

Quando eu testei os sistemas, reparei que o sistema mais simples (Winsocket) suporta apenas uma comunicação Ponto-a-Ponto, isto quer dizer, o servidor suporta apenas 1 conexão. Neste caso ficou difícil entender então resolvi pesquisar na internet e desenvolver outro Chat utilizando Winsocket.

1ª Etapa
Para começar o Chat vamos criar a sua interface, neste caso adicione no programa os seguintes componentes:

Inserindo:
TMemo => Coloque o nome como Quadro.
Tmemo => Com nome de Status.

TGroupBox => Coloque o nome como C_Comandos
TEdit => Coloque dentro do TGroupBox (C_Comandos) com o nome de C_Texto
TEdit => Com nome de Host.
TEdit => Com nome de Apelido.
TButton => Com nome de Conectar.

TButton => Com nome de Servir.
2 Tlabel => Com caption Servidor e Apelido.

Agora adicione os seguintes componentes.
TclientSocket => Com nome de S_Cliente.
TserverSocket => Com nome de S_Server.

(VEJA FIGURA AO LADO)

Agora renomeie o Form1 para ChatFal. (Clique no Form depois vá em name e mude).

Vamos tentar deixar o Object Treeview mais ou menos assim:

Pronto agora tente organizar desta forma:

2ª Etapa

Bom nesta etapa vamos começar a programar o chat.

a) O primeiro evento que o programa irá executar será o TchatFal.FormCreate, clique 2x no formulário, e deixe este procedimento assim:

    
procedure TChatFal.FormCreate(Sender: TObject); {Limpa o quadro}
    begin
        Quadro.Text := '';
    end;

Explicação:

Com isto, assim que o formulário inicie, o conteúdo do componente QUADRO será apagado.

b) O segundo evento a ser programado será 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).

Primeiro se declara a procedure.

procedure C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

Depois vamos programar a procedure.

procedure TChatFal.C_TextoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin

        if Key = VK_Return then
            begin
                S_Cliente.Socket.SendText(C_Texto.Text + '::::' + Apelido.Text);
                C_Texto.Text := '';
            end;
    end;


Explicação:
Nos criamos uma procedure que utiliza uma variável “Key” do tipo Word, e declaramos também o uso do Shift (Se não declarar o uso do shift não funciona).

 if Key = VK_Return then => Se a tecla digitada for igual ao [ENTER] então execute.

S_Cliente.Socket.SendText(C_Texto.Text + '::::' + Apelido.Text); => Envia o texto para o servidor no formato (Mensagem::::Apelido) este formato será explicado mais na frente.

 C_Texto.Text := ''; => Limpa o conteúdo da TEdit C_Texto.

c) Vamos programar a procedure do terceiro evento. Este será para o botão “Conectar” onde ao clicar o programa irá pegar o conteúdo da Tedit “Host” e tentar conectar-se.

Clique 2x em cima do botão Conecta, e deixe da seguinte forma:

procedure TChatFal.ConectarClick(Sender: TObject);
    begin
        if S_Cliente.Active then
            begin
                S_Cliente.Active := False;

                Conectar.Caption := 'Conectar';
            end
         else begin
                S_Cliente.Host := Host.Text;
                S_Cliente.Active := True;
        end;

    end;

Explicação:

if S_Cliente.Active then => Primeiro verificamos se o TclientSocket esta ativo (isto é se a conexão já esta ativa).

 S_Cliente.Active := False; => Se tiver ativo ele desativa (Desconecta).

Conectar.Caption := 'Conectar'; => Altera o caption do TButton (Conectar) para 'Conectar'.

 else begin => Caso a conexão já esteja desativada, isto é S_Cliente.Active = False então ele vai se conectar.

 S_Cliente.Host := Host.Text; => Pega o conteudo de Host isto é o endereço IP do servidor, e coloca na propriedade Host do componete S_Cliente.

S_Cliente.Active := True; => Ativa a conexão.

3ª Etapa

Agora vamo programar os eventos do conexão do Lado Cliente.

Primeiro declare os procedimentos abaixo:

procedure S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);

procedure S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure S_ClienteRead(Sender: TObject; Socket: TcustomWinSocket);

Estes são os eventos do componente TclientSocket que colocamos no programas e renomamos para S_Cliente.

Agora vamo programa-los um por um.

Primeiro OnConnect.

procedure TChatFal.S_ClienteConnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        Status.Lines.Add('Cliente ::> Conectado a: ' + S_Cliente.Host);
        Conectar.Caption := 'Desconectar';

        Apelido.Enabled := False;
        S_Cliente.Socket.SendText('NICK::::' + Apelido.Text);
    end;

Explicação:
Este evento somente ocorre quando há sucesso de conexão, isto é logo após estabelecer conexão com o servidor sem erros.

 Status.Lines.Add('Cliente ::> Conectado a: ' + S_Cliente.Host); => Aqui escrevemos no status Status.Lines.Add uma mensagem informando o cliente que ele teve sucesso na conexão.

 Conectar.Caption := 'Desconectar'; => Muda-se o caption do TButton (Conectar) de 'conecta'r para 'desconectar', pois agora sua função será encerrar a conexão.

Apelido.Enabled := False; => Depois desabilitamos o Tedit do Apelido (Apenas para o cliente não mudar de apelido durante a conexão o que não afeta nada caso mude).

S_Cliente.Socket.SendText('NICK::::' + Apelido.Text); => Enviamos para o servidor um Texto seguindo o mesmo formato que a procedure de escrever S_Cliente.Socket.SendText. Repare que desta vez o formato muda um pouco, antes era (Mensagem::::Apelido) agora é (NICK::::Apelido). Isto serve para diferenciar o tipo de mensagem, a primeira é uma mensagem normal, a segunda informa que você entrou no servidor.

O Tratamento desses formatos fica no lado do servidor que veremos em breve.

Segundo evento é o OnDisconnect.

procedure TChatFal.S_ClienteDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    begin
        Status.Lines.Add('Cliente ::> Desconectado ');

        Conectar.Caption := 'Conectar';
        Apelido.Enabled := True;
    end;

Explicação:

Este evento é o oposto do evento anterior, ele somente é executado quando a conexão é desfeita.

Status.Lines.Add('Cliente ::> Desconectado '); => Informamos ao cliente com uma mensagem no status Status.Lines.Add.

Conectar.Caption := 'Conectar'; => Mudamos o caption do TButton (Conectar) para "conectar".

Apelido.Enabled := True; => Habilitamos a TEdit (Apelido).

Terceiro evento é o OnError.

procedure TChatFal.S_ClienteError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    begin
        Status.Lines.Add('Cliente ::> ERRO ao tentar conectar a: ' + S_Cliente.Host);

    end;

Explicação:

Bastante simples, em caso de erro de conexão informa no status a mensagem ERRO ao tentar conectar a: ' + S_Cliente.Host.

Quarto e ultimo evento da TclientSocket, OnRead.

procedure TChatFal.S_ClienteRead(Sender: TObject; Socket: TCustomWinSocket);
    begin
        Quadro.Lines.Add(Socket.ReceiveText);
    end;

Explicação:
Este evento ocorre quando o TClientSocket recebe dados através da conexão ativa. Como a mensagem já vem formatada pelo servidor basta apenas adicionar no quadro  Quadro.Lines.Add(Socket.ReceiveText); .

Pronto aqui finalizamos a programação do lado Client do nosso chat.

EDITANDO AS PROPRIEDADES DO COMPONETE TClientSocket (S_Cliente).

Agora vamos parar um pouco a programação, e vamos alterar as propriedades do nosso componente TclientSocket. Onde aqui vamos configurar a porta de comunicação e também vamos colocar os eventos que programamos nos seus devidos lugares.

Primeiro selecione o ícone do componente TclientSocket (S_Cliente) no formulário, depois vá na janela do “Object Inspector” e em propriedades coloque Active em FALSE (Para iniciar desconectado) e em Port abaixo de Name coloque a seguinte porta (666) ou outra que você quiser e que não esteja sendo usada pelo sistema.

Agora vá na aba Eventos e configure os eventos como esta abaixo na IMG.

Pronto o lado cliente já esta pronto agora vamos programar o lado servidor do nosso chat.

4ª Etapa

Nesta etapa vamos primeiro programar o evento do TButton "Servir" (Eu coloquei a caption deste botão como (Iniciar Servidor).

Clique 2x no botão para programar o evento.

procedure TChatFal.ServirClick(Sender: TObject);
    begin
        if S_Server.Active = True then
            begin
                S_Server.Active := False;

                Status.Lines.Add('Servidor ::> Servidor Desligado!');
                Servir.Caption := 'Iniciar Servidor';
                S_Cliente.Active := False;
                Host.Enabled := True;
                Conectar.Enabled := True;

            end
        else begin
                S_Server.Active := True;
                Servir.Caption := 'Parar Servidor';
                Host.Enabled := False;
                Conectar.Enabled := False;

                S_Cliente.Host := '127.0.0.1';
                S_Cliente.Active := True;
            end;
    end;

Explicação:
Primeiro da mesma forma que o botão de conectar primeiro verificamos o estado do servidor. Se ele está servindo ou esta parado.

  if S_Server.Active = True then => Caso esteja ativo, isto é caso ele esteja esperando conexões na porta configurada, então vamos desligar.

S_Server.Active := False; => Desliga o servidor.

Status.Lines.Add('Servidor ::> Servidor Desligado!'); => Informa no status que o servidor foi desligado.

Servir.Caption := 'Iniciar Servidor'; => Muda o caption do TButton (Servir) para 'iniciar servidor'.

S_Cliente.Active := False; => Desativa a conexão do cliente. (Ao iniciar o servidor automaticamente o programa se conecta ao servidor).

 Host.Enabled := True; => Abilita o campo de escolha do IP.

Conectar.Enabled := True; => Abilita o botão de conectar.

else begin => Caso o servidor não esta ativo, então ative.

S_Server.Active := True; => Ativa o servidor, e neste momento o servidor fica esperando conexões na porta configurada.

Servir.Caption := 'Parar Servidor'; => Muda o caption do TButton (Servir) para 'parar servidor' pois sua função agora é parar.

Host.Enabled := False; => Desativa o campo de escolha do IP (O cliente vai se conectar no localhost).

 Conectar.Enabled := False; => Desativa o botão de conectar, pare evitar desconexão do cliente com o servidor local.

 S_Cliente.Host := '127.0.0.1'; => Força o host do S_Cliente para localhost (127.0.0.1).

 S_Cliente.Active := True; => Conecta no servidor como cliente.

O IP '127.0.0.1' Corresponde a própria maquina, neste caso ao ligar o servidor ele também se conecta como cliente e desabilita as opções de conexão, caso desligue o servidor ele também se desconecta.

Agora o passo seguinte e declarar os procedimentos dos eventos do S_Server.

procedure S_ServerListen(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);

procedure S_ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure S_ServerClientRead(Sender: TObject; Socket: TcustomWinSocket);

Os eventos são parecidos com os eventos do S_Cliente com diferença que não usa o evento OnError e agora existe o evento OnListen.

Vamos aos eventos.

Primeiro o evento OnListen.

procedure TChatFal.S_ServerListen(Sender: TObject;
Socket: TCustomWinSocket);
    begin
        Status.Lines.Add('Servidor ::> Servidor Ligado!');
    end;

Explicação:
Este evento ocorre quando o servidor é ligado, isto é quando ele começar a escutar na porta determinada. Quando isto ocorre ele simplesmente escreve no status a mensagem de que o servidor está ligado.
Status.Lines.Add('Servidor ::> Servidor Ligado!');

Segundo evento será o OnClientConnect.

procedure TChatFal.S_ServerClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
    begin
        Status.Lines.Add('Servidor ::> Usuário Conectado => '+ Socket.RemoteAddress);

     end;

Explicação:

Este evento ocorre quando o servidor recebe uma conexão de algum cliente. Quando isto ocorrer vamos escrever no status do servidor uma mensagem informando que um novo usuário se conectou e qual seu IP (Socket.RemoteAddress).

Status.Lines.Add('Servidor ::> Usuário Conectado => '+ Socket.RemoteAddress

Terceiro evento será o OnClientDisconnect.

procedure TChatFal.S_ServerClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);

    begin
        Status.Lines.Add('Servidor ::> Usuário Desconectado => '+ Socket.RemoteAddress);
    end;

Explicação:
Este evento ocorre quando o servidor termina uma conexão de algum cliente. Quando isto ocorrer vamos escrever no status do servidor uma mensagem informando que o usuário se desconectou e qual seu IP (Socket.RemoteAddress).
Status.Lines.Add('Servidor ::> Usuário Desconectado => '+ Socket.RemoteAddress);

Quarto e mais importante evento OnClientRead.

procedure TChatFal.S_ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
    var texto: array[0..1] of string;
    temptexto: string;
    Index: integer;
    begin

        temptexto := Socket.ReceiveText;
        texto[0] := Copy(temptexto, 1,Pos('::::', temptexto) -1);
        texto[1] := Copy(temptexto, Pos('::::', temptexto) + Length('::::'),Length(temptexto));
        if texto[0] = 'NICK' then {Verifica se a mensagem eh de entrada}
            begin

                WITH S_Server.Socket DO BEGIN {Se a msg for de entrada avisa a todos os clientes quem entrou }
                    FOR Index := 0 TO ActiveConnections-1 DO BEGIN
                        Connections[Index].SendText(texto[1] + ' entrou na sala: ');
                    END;
                END;
            end

        else

            begin
                WITH S_Server.Socket DO BEGIN {Se nao for de entrada, então eh msg normal, no caso passa para todos a msg}
                    FOR Index := 0 TO ActiveConnections-1 DO BEGIN
                        Connections[Index].SendText('(' + texto[1] + ') escreveu: ' + texto[0]);
                    END;
                END;

                Status.Lines.Add('Servidor ::> ' + texto[1] + ' (' + Socket.RemoteAddress + ') escreveu: '+ texto[0]);
            end;

end;


Explicação

Este evento é o mais importante do chat, pois é nele que realmente o chat irá funcionar. O evento ocorre quando o servidor recebe dados do cliente, neste caso ele terá que receber a mensagem e repassar para todos os clientes conectados (Broadcasting).

Esta parte foi difícil desenvolver, pois no exemplo que vem no Delphi (WinSocket) ele não envia para todos os usuários a mensagem, ele apenas adiciona na Memo a informação recebida.

Depois de uma boa pesquisada no GOOGLE sobre WinSocket eu achei uma solução funcional.

Bom vamos passo a passo do código.

var texto: array[0..1] of string; => Este array será necessária para formatação dos dados.

 temptexto: string; => Está variável será necessária para formatação dos dados.

 Index: integer; => Variável de controle para o loop de broadcast.

temptexto := Socket.ReceiveText; => Variável temptexto recebe os dados enviados pelo cliente Socket.ReceiveText.

 texto[0] := Copy(temptexto, 1,Pos('::::', temptexto) -1); => Separa a informaçã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ções sobre as funções Pos, Length e Copy. Pois são muito uteis.

texto[1] := Copy(temptexto, Pos('::::', temptexto) + Length('::::'),Length(temptexto)); => Aqui texto[1] pega tudo que estiver depois do separador '::::'.

if texto[0] = 'NICK' then => Se o que estiver antes de '::::' for NICK então foi mensagem de entrada.

 WITH S_Server.Socket DO BEGIN => Bom aqui eu estou dizendo que com o Objeto S_Server.Socket Faça. No help do Delphi tem uma explicação sobre 'WITH'.

 FOR Index := 0 TO ActiveConnections-1 DO BEGIN=> Um laço usando FOR, até o final das conexões. (ActiveConnections vem do objeto S_Server através do WITH).

Connections[Index].SendText(texto[1] + ' entrou na sala: '); => Vai enviando mensagens para todas as conexões da primeira até a ultima, informando quem entrou no servidor.

Else => Se não for 'NICK' o que vem antes do separador '::::', então deve ser mensagem.

WITH S_Server.Socket DO BEGIN => Denovo WITH.

FOR Index := 0 TO ActiveConnections-1 DO BEGIN => Laço de 0 até o final das conexões.

Connections[Index].SendText('(' + texto[1] + ') escreveu: ' + texto[0]); => Envia para todas as conexões a mensagem enviada.

Status.Lines.Add('Servidor ::> ' + texto[1] + ' (' + Socket.RemoteAddress + ') escreveu: '+ texto[0]); => Adiciona no status do servidor uma cópia da mensagem.

Pronto agora terminamos de programar os eventos do componente S_Server. Agora vamos editar suas propriedades no Object Inspector da mesma forma que configuramos o S_Client.

Deixamos Active = False
e Port = 666 (Ou a porta que você usou no S_Client).

e os eventos (Events)

OnClientConnect = S_ServerClientConnect
OnClientDisconnect = S_ServerClientDisconnect
OnClientRead = S_ServerClientRead
OnListen = S_ServerListen

O resto dos eventos ficam em branco como na imagem abaixo:

TESTANDO O CHAT

Pronto salve tudo e compile, agora vá na pasta em que o programa foi compilado e abra 3 janelas do programa.

No primeiro coloque o apelido como Administrador e clique em iniciar o Servidor.
No segundo coloque como usuario1 digite o endereço local (127.0.0.1) e clique em conectar.
No Terceiro coloque como usuario2 digite o endereço local (127.0.0.1) e clique em conectar.

Pronto agora teste a comunicação entre os 3.

Bom espero que tenha funcionado seu CHAT, você pode baixar o código fonte completo do chat e a versão binária do mesmo neste link abaixo:

http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/c_h_a_t_f_a_l.zip

(O nome do arquivo esta separado por _ para evitar de ser bloqueado pelo Proxy da rede da FAL.)

Links de referência usados:
http://www.guiadodelphi.com.br
http://www.delphi-forum.de

Este tutorial pode ser reproduzido e publicado livremente, desde que se mantenha os créditos do autor.
12 de Março de 2005.
Thiago Melo
(thiago@dolphinconsult.com.br).


54 Responses to “Criando um Chat no DELPHI utilizando Sockets”

  1. By Dener on set 4, 2007 | Reply

    Ola gostaria se tem como implementar isso p/ ser usado na web ou so funciona local?
    grato

  2. By Thiago Melo on set 4, 2007 | Reply

    Sim da para implementar para web, já que é uma conexão TCP/IP, basta apenas conectar no seu IP real da internet.

    Caso esteja usando internet compartilhada, firewall, e etc tem que configurar estes equipamentos ou programas antes.

  3. By Marcos on set 10, 2007 | Reply

    Amigo Thiago, não li o o artigo todo mas fica fácil implementar o Chat onde eu consiga conversar com um usuário por vez assim como o MSN?

  4. By Thiago Melo on set 11, 2007 | Reply

    O chat é bastante amador, mas nele da pra conversar com uma ou várias pessoas ao mesmo tempo, ele só não tem um bom controle de quem esta conectado, mas funciona.

    basta rodar o chat em 2 maquinas diferentes rodar o server em uma e conectar com a outra (lembre-se de configurar seu firewall)

  5. By jobim on out 6, 2007 | Reply

    Thiago Melo, fiz tudo certo aqui, mas deu um erro!!

    "asynchronous socket error 10049"

    SE VC PUDESSE AJUDAR...

    DEIS DE JA AGRADECIDO

  6. By Thiago Melo on out 11, 2007 | Reply

    Isso acontece quando o programa tenta escutar um IP:PORTA e o mesmo já está sendo utilizado.

    Segundo o manual da M$ do winsock

    WSAEADDRNOTAVAIL
    10049

    Cannot assign requested address.

    The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).

  7. By Gabriel on nov 4, 2007 | Reply

    Cara... show seu artigo... adorei
    estava querendo fazer um simples joguinho em rede...
    seu artigo me deu um bom começo de como fazer
    vlw... PARABÉNS

  8. By Jhony on nov 5, 2007 | Reply

    Ohh tiago me dá uma força...
    toda hr dá esse erro e naum tem como fazer mais nada:

    Could not find source location to add methot C_TextoChange."END" or INITIALIZATION not found in unit souce.

    desde já agradeço

  9. By Thiago Melo on nov 7, 2007 | Reply

    @Gabriel, valeu velho boa sorte no jogo.

    @Jhony esse erro deu com o source do chat? estranho isso me confirma ai, que eu estou meio esquecido de Delphi, faz anos que não programo em Delphi.

  10. By marcos on nov 10, 2007 | Reply

    ae thiago, vc tem msn para conversarmos? eu queria saber como posso colorir os nicks?

  11. By Francisco on nov 18, 2007 | Reply

    Parabéns Thiago

    Artigo muito bom...

  12. By Thiago Melo on nov 20, 2007 | Reply

    @marcos tenho gtalk, thiago@oxente.org

  13. By João on dez 15, 2007 | Reply

    Show de bola

  14. By Reinaldo Reis on jan 18, 2008 | Reply

    cara muito show... o que eu aprendi, foi sem valor! muito obrigado. valeu mesmo!!!!!!!!!!!!

  15. By Alex Sandro on mar 28, 2008 | Reply

    Ola é possivel colocar este Chat no meu site. se for como.

  16. By Thiago Melo on abr 2, 2008 | Reply

    Pra site é mais complicado converter, programação WEB e bem mais fácil que essa aí, existem muitos chats prontos e de graça na web basta procurar.

  17. By Gabriela Nunes on abr 4, 2008 | Reply

    Olá, gostei muito do artigo, porém, ao tentar testar o programa, houve o seguinte erro, já citado anteriormente: "Ashynchrous spcket error 10049", e não sei como arrumá-lo...se pudesse me ajudar, ficaria muito feliz, obrigada pela atenção!!

  18. By Thiago Melo on abr 8, 2008 | Reply

    "Ashynchrous spcket error 10049" Olá Gabriela, eu já comentei sobre esse erro aqui, tipo ele da quando a porta e o ip já estão utilizados.

    Pode ser o programa travou a porta, não sei se o código fonte do chat esta no arquivo que eu botei o link mas qualquer coisa eu mando para voce.

    Faz tempo que nao mexo com delphi, então nao me lembro de muita coisa.

  19. By André on mai 8, 2008 | Reply

    olá... parabéns pelo chat..
    mas é o seguinte:
    aqui ta dando um erro Ashynchrous socket error 10061, oq será q é isto?
    vlw

  20. By André on mai 8, 2008 | Reply

    ops...
    desculpa, entendi o porque q dava este erro
    só faltava alguem estar como servidor... rsrsrs
    mas vlw, parabéns pelo chat..
    flw

  21. By André on mai 12, 2008 | Reply

    como posso fazer para que este chat possa ter a função de enviar arquivos, assim o servidor pode mandar um arquivo p/ o cliente, e visse e versa?

  22. By Thiago Melo on mai 14, 2008 | Reply

    @Andre, cara eu ainda não estudei essa parte de envio de arquivos em Delphi eu tava vendo isso em C++, porem eu apanhei muito pra fazer o chat e acabei colocando de lado um pouco.
    Reinventar a roda é bom para aprender mas se for pra algo sério e bom da uma olhada em algo pronto, algum plugin e etc.

  23. By Eric on mai 31, 2008 | Reply

    Thiago, muito interativo seu post!
    é possível interagir com um chat na web "que ja esteje rodando"?
    a partir de um cliente socket, tipo passando dados/recebendo e montando o chat dentro do delphi?
    abraços!

  24. By Luciano on jun 2, 2008 | Reply

    Thiago,

    Muito bom o tópico. Eu gostaria de saber se acaso o lado client da aplicação sair abruptamente o que acontece? Será avisado? Caso não tem com ser feito uma rotina para exibir quem se desconectou abruptamente inclusive com número da conexão. Pelos testes que fiz aqui, qdo um cliente se disconecta de maneira normal é avisado ao server.

  25. By Thiago Melo on jun 3, 2008 | Reply

    De maneira brusca ele não avisa mesmo, quando eu fiz esse chat não cheguei a ir a fundo no protocolo, coisas como enviar mensagem privada, ou arquivo não seriam possíveis ate que eu soubesse como controlar os clientes no servidor.
    A partir do momento que eu consiga controlar as conexões com algum tipo de identificação no servidor eu posso avisar quando alguem sai de meneira brusca.

  26. By Thiago Melo on jun 3, 2008 | Reply

    @Eric, eu creio que seja possivel sim, porem eu acho que é mais facil e pratico fazer um somente com os recursos da web, como PHP e AJAX, eu tenho um rodando no meu forum como uma shoutbox, sem refresh.
    http://killermonkeys.net (ver o bloco da esquerda)

  27. By anonimo on jun 16, 2008 | Reply

    filé do brasil
    muito bom cara continue assim

  28. By Rock2099 on jun 30, 2008 | Reply

    Muito boa dica de chat, e forum bem interativo, nota 11.

  29. By LUANA PADILHA on jul 4, 2008 | Reply

    THIAGO eu estou no inicio de aprendizagem de delphi só que tenho que apresentar um trabalho pra feira tecnica e gostei mto do seu chat
    Antes de iniciar o desenvolvimento gostaria de saber sua opiniao se é mto complicado pra uma pessoa iniciante como eu!!??

    sera q consigo??

    ah e }Parabéns..!!

  30. By Thiago Melo on jul 4, 2008 | Reply

    @Luana,
    Delphi em si é fácil, eu hoje não sei mais nada de Delphi depois que paguei a materia meio que apaguei da mente, mas quando fiz o chat eu não sabia NADA de delphi, eu sabia pascal um pouco, foi lendo na internet e aprendendo.
    O chat é bem simples de fazer e entender e o código fácil de se explicar no caso de apresentar.

  31. By LUANA PADILHA on jul 4, 2008 | Reply

    Hum eu consegui fazer só q ta dando um um erro Ashynchrous socket error 10061!! o que pode ser isso??

  32. By LUANA PADILHA on jul 5, 2008 | Reply

    thiago tem diferença nesse memo o ultimo que esta como status pro memo de cima que é o quadro??

  33. By David on jul 14, 2008 | Reply

    Parabéns Thiago!Show seu artigo!
    Encontrei um pequeno problema e quem sabe vc pode dar uma força. Tenho 3 placas de rede instaladas no meu computador e o servidor monitora o ip da placa que não é a que possui conexão com a internet. Vc sabe como eu poderia escolher a interface a ser usada, no caso a que possui conectividade com a internet?

    Abraço

  34. By Thiago Melo on jul 16, 2008 | Reply

    @LUANA, nossa nem vi que tinha novo comentário.
    O Ashynchrous socket error 10061 é por que ele não encontrou o servidor, logo acima tem alguem com o mesmo problema e resolveu ligando o server. E não os Tmemo são iguais eu so colori mais o outro.

    @DAVID, não sei como que ele escolhe a Ethernet, achei que ele ficasse escutando no 0/0 (toda a rede) veja se a interface da internet não esta com um firewall, ou você pode colocar o IP da placa que você deseja no S_Server.Host que ele vai dar bind nessa placa exclusivamente.

  35. By Gustavo Martins on ago 3, 2008 | Reply

    Não sei se o assunto já morreu, mas gostaria de dar a minha contribuição. Sobre o Erro: "Ashynchrous socket error 10061" Falha de conecção com Servidor, resolvi da seguinte maneira:

    No evento OnError do TClientSocket setar o parametro manipulador de erro ErrorCode:= 0; p/ anular a visualização da messagem de erro e evitar a iniciação do ESocketError.

    No evento OnErro tb traz dois parametros p/ identificar a natureza do erro, e assim poder trata-las adequadamente, são elas:

    var ErroCode do tipo Integer
    e
    ErrorEvent do tipo TErrorEvent

    [Capturar Número do Erro] Declarar uma variável do tipo Integer p/ capturar o número do erro:

    num_erro:= ErroCode; // captura o número do erro
    ErroCode:= 0; // Anula manipulador de erro
    Memo1.Lines.Add('Erro: ' + IntToStr(num_erro)); //visualiza o número do erro em TMemo

    [Natureza do Erro]

    Verificado o que provocou o erro, capturando resultado do parametro ErrorEvent: TErrorEvent;

    // soquete eeGeneral recebeu uma mensagem de erro que não se encaixa em qualquer uma das seguintes categorias
    if ErrorEvent = eeGeneral then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeDisconnect');

    //eeSend Ocorreu um erro ao tentar escrever para o soquete de conexão
    if ErrorEvent = eeSend then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeSend');

    //eeReceive Ocorreu um erro ao tentar ler a partir da conexão socket
    if ErrorEvent = eeReceive then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeReceive');

    //Uma ligação eeConnect pedido que foi já aceito não pôde ser concluída
    if ErrorEvent = eeConnect then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeConnect');

    //eeDisconnect Ocorreu um erro ao tentar fechar uma conexão
    if ErrorEvent = eeDisconnect then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeDisconnect');

    //eeAccept Um problema ocorreu durante a tentativa de aceitar solicitação de uma conexão cliente.
    if ErrorEvent = eeAccept then memo1.Lines.Add('Erro número: ' + IntToStr(num_erro) + ' eeAccept');

    Espero ter a ajudado.

    Abraços a todos

    Gustavo Martins

  36. By Thiago Melo on ago 4, 2008 | Reply

    Valeu gustavo.

  37. By Lucas Oliveira on ago 5, 2008 | Reply

    Eu estaria interessado em ter uma ajuda para um jogo de cartas, estilo super trunfo.

    o básico do jogo tem como principio básico um chat parecido com o seu.

    é uma estrutura cliente/servidor

    depois que 4 pessoas entrarem no chat, todas apertarem um botão com status pronto (SIM, NÃO) e o jogo inicia quando todos tem status SIM.

    o servidor embaralha as cartas, distribui todas as cartas.. então o primeiro jogador escolhe um dos atributos, que é comparado com todos os outros jogadores e o maior leva todas as cartas que são colocadas no fim do baralho.

    o jogo termina quando o vencedor obter todas as cartas.

    quero sua opinião sobre isso, pois vou precisar de ajuda. e nao sei aonde procurar materiais para mim ter uma base.

    até mesmo o codigo fonte de um chat simples como o seu ajudaria muito.

    o link está quebrado.

    se puder me ajudar, escreve pra hiro@mundoavatar.com.br

  38. By Thiago Melo on ago 5, 2008 | Reply

    Olá Lucas, sobre o seu projeto com relação a Delphi eu não sei se posso te ajudar pois faz anos luz que não mexo com Delphi, mas o link do chat eu arrumei estava com um domínio antigo e agora já está ok.

  39. By Lucas Oliveira on ago 6, 2008 | Reply

    nao consigo baixar.
    :(

    ja removi todos os underlines
    mas ainda dá como pagina nao encontrada.

  40. By Thiago Melo on ago 7, 2008 | Reply

    Cara não e pra remover os underlines e so clicar

    http://reiserfs.killermonkeys.net/Thiago/Delphi/xhat/c_h_a_t_f_a_l.zip

  41. By claudionor on set 2, 2008 | Reply

    Cara, preciso apresentar um trabalho na faculdade, onde tenho que criar um chat criptografado. Tem como me dar essa dica.

    Valeu mesmo.

  42. By Thiago Melo on set 5, 2008 | Reply

    Claudionor, cara nunca tive experiência com isso, mas procura ler sobre OpenSSl.

  43. By Junior on out 14, 2008 | Reply

    Onde posso achar esse componente Tclientsocket

  44. By Thiago Melo on out 15, 2008 | Reply

    Rapaz veio no Delphi que usei acho que Delphi 7

  45. By Diógenes on out 23, 2008 | Reply

    @Junior

    dei uma estudada, tenho um projeto de chat pra fazer e achei esse interessante, ainda to aprendendo

    a TClientSocket e TServerSocket pelo que lí, vem na versão do Delphi 6, no 7 não tem

    porém se vc procurar no diretório do delphi 7 tem um arquivo binário que instala esses 2 componentes

    só n lembro o nome dele, da uma pesquisada no google, q na versão do 7 tem como add eles sim

  46. By Danilo on nov 1, 2008 | Reply

    Ola,pessoal quando eu teclo enter a menssagem nao é enviada,alguem poderia me ajuda?

  47. By Thiago Melo on nov 6, 2008 | Reply

    @Danilo, da uma olhada no evento do enter. Não lembro qual é

  48. By Francisco César on nov 8, 2008 | Reply

    Ao ver esse chat tive a idéia de incorporá-lo num joguinho da forca via rede que estou desenvolvendo. O problema é que não tenho experiência em sockets. Se alguém quiser me ajudar com isso, estou disponibilizando o jogo no link http://www.franciscocesar.com/jogo.forca.v1.zip. O chat do Thiago funciona sem problemas, mas a aplicação da forca só funciona de
    maneira isolada em cada micro; isso é óbvio pq ainda não implementei nada por falta
    de experiência, como já disse. Um abraço a todos, especialmente ao Thiago pelo compartilhamento de seu programa.

  49. By Francisco César on nov 8, 2008 | Reply

    Esqueci um detalhe...Imagino que o jogo que postei acima poderia funcionar da seguinte forma: Como a interação entre os 2 jogadores não se dá o tempo todo, ou seja, hora joga um, hora jogo outro; em outras palavras, enqto 1 joga (tenta adivinhar a palavra), o outro assiste até acabar o jogo, diferente de uma disputa em tempo real, por exemplo, o que seria mto mais complicado em termos de socket. Então pensei que deve existir algum recurso tipo, o que aparecer aqui (micro 1), mostre lá no outro (micro 2), algo assim. Espero ter sido claro. Abraços...chico

  50. By Thiago Melo on nov 10, 2008 | Reply

    @Francisco a ideia e boa, eu mesmo queria tentar botar mais controle no chat, porem meu conhecimento em sockets de delphi era bem limitados, hoje é nulo hahaah lembro de nada. Boa sorte ai.

  51. By Francisco César on nov 13, 2008 | Reply

    Valeu Thiago. Acertei diversos bugs que tinha o anterior jogo; caso queira, acesse http://www.franciscocesar.com/Project1.exe
    Assim que conseguir o funcionamento pela rede, deixo aqui pra quem quiser brincar. Abraço.

  52. By Mustang on nov 18, 2008 | Reply

    Aê,show de bola o chat

    Eu tava querendo aprender fazer um chat pra conectar na uol...olha como exemplo os chat clients do alteradoserevoltados.com

    Tem como vc me dá alguma dica?

    Desde já,agradeço

  53. By Mustang on nov 18, 2008 | Reply

    Eu tinha esquecido..Não quero atrapalhar o chat da Uol.

    Tenho a simples ideia de criar um bot q responde perguntas..tipo um joguinho de perguntas e respostas...

    Vlw

  54. By Diógenes on nov 22, 2008 | Reply

    Pô, eu fiz várias modificações nesse chat, tais como skins e funções a mais..porém agora preciso criar, tipo um evento para que quando alguém receber alguma mensagem, tipo acontecesse igual msn, pro cara ver que recebeu uma mensagem e tal..caso alguém queira ver como minhas modificações estão, mail me dgs_alves@live.com!

    agradeço qualquer ajuda desde já!

Post a Comment