Usando o Controle Winsock - II - Que tal um Chat ....


No artigo - Usando o Controle Winsock  - demos uma introdução básica em como usar o controle Winsock. Vamos mostrar agora alguns exemplos práticos de projetos usando o Winsock.

Enviando e Recebendo Mensagens com o Winsock

Para trabalhar com o Winsock em uma rede ( a internet é uma grande rede ) precisamos de um cliente que requisita as informações e de um servidor que funciona como o garçom que nos dá a informação solicitada.  

O Cliente deve se conectar ao Servidor através de uma porta de comunicação , feita a conexão podemos transferir arquivos e dados entre Cliente e Servidor. Uma das primeiras coisas que você deve saber é o nome ou o endereço IP do computador ao qual deseja se conectar o resto não importa.

Para verificar se as suas configurações TCP/IP estão corretas , vamos usar o programa Ping. Abra uma janela do DOS e digite a seguinte instrução : Ping nome_do_computador  ou Ping Endereço_IP . Abaixo o resultado para minha máquina , onde usei a instrução : Ping macorati 

Se o seu endereço IP estiver configurado errado os pacotes enviados não seriam recebidos e você teria Pacotes perdidos durante a transação

Se você não sabe o nome do seu Computador e esta em dúvida quanto a configuração do seu TCP/IP. Não se desespere vamos mostrar , usando o Winsock , como você pode obter esta informação...

Criando o módulo Servidor

Vamos agora criar o módulo servidor da nossa aplicação:

Para obter o nome do seu computador insira a seguinte instrução no evento Load do Formulário:

Private Sub Form_Load()
   MsgBox " O nome do seu computador é : " & wskServidor.LocalHostName
End Sub

Pressione F5 e rode seu projeto ...   Você deverá ver uma caixa de mensagem com o nome do seu computador...

Bem , vamos continuar :

No evento Load do formulário frmServidor insira o código a seguir:

Private Sub Form_Load()
    wskServidor.LocalPort = 100
    wskServidor.Listen
    Caption = " Winsock - Servidor - " & UCase(wskServidor.LocalHostName)
End Sub
  1. Aqui definimos a porta local como a porta 100 (poderia ser a 1000 , etc.. )
  2. Invocamos o método Listen . O servidor estará 'escutando' esta porta
  3. Exibimos o nome do computador

Agora no evento ConnectionRequest insira o código abaixo:

Private Sub wskServidor_ConnectionRequest(ByVal requestID As Long)
   If wskServidor.State <> sckClosed Then wskServidor.Close
   wskServidor.Accept requestID
End Sub

Este evento serve para que possamos saber o que fazer se uma conexão for requisitada. Então...

  1. Verificamos se o estado do controle esta fechado
  2. Se não estiver fechado , fechamos antes de aceitar uma nova conexão
  3. Aceitamos a requisição com o parâmetro RequestId

No evento DataArrival iremos inserir o seguinte código

Private Sub wskServidor_DataArrival(ByVal bytesTotal As Long)
   Dim strdados As String
   wskServidor.GetData strdados
   TxtReceber.Text = strdados
End Sub

Este evento serve para dizer o que o controle deve fazer quando os dados chegarem. 

  1. Quando o dado chega do modulo cliente (vamos construí-lo a seguir) , o método GetData é invocado e recebe os dados na variável strdados 
  2. A seguir os dados são exibidos na caixa de texto txtreceber

Finalmente o codigo do botão cmdEnviar:

Private Sub cmdEnviar_Click()
     wskServidor.SendData txtEnviar.Text
End Sub

Aqui apenas enviamos os dados que estão na caixa de texto txtEnviar.  Pronto a primeira parte esta pronta...  

Criando o módulo Cliente

Para completar o projeto vamos criar o módulo Cliente :

Agora o código:

Primeiro digite o código a seguir no evento Load do formulário frmCliente:

Private Sub Form_Load()
   wskCliente.RemotePort = 100
   Caption = "Usando Winsock - Cliente " & wskCliente.LocalHostName
End Sub
  1. Observe que aqui devemos configurar a porta remota como sendo a mesma que informamos no módulo servidor, afinal o servidor está esperando a conexão nesta porta.
  2. Exibemos o nome da Estação Cliente e o nome do computador

No evento DataArrival temos o seguinte código:

Private Sub wskCliente_DataArrival(ByVal bytesTotal As Long)
   Dim strdados As String
   wskCliente.GetData strdados
   TxtReceber.Text = strdados
End Sub
  1. Aqui temos o código igual ao usado no servidor , apenas muda o nome do controle. Os dados são recebidos e exibidos na caixa de texto TxtReceber

Agora o código do botão Conectar - cmdConectar :

Private Sub cmdConectar_Click()
  wskCliente.RemoteHost = txtComputador.Text
  wskCliente.Connect
End Sub
  1. O cliente tenta se conectar com o computador informado em txtComputador através do método Connect

Código do botão Enviar - cmdEnviar :

Private Sub cmdEnviar_Click()
   wskCliente.SendData txtEnviar.Text
End Sub
  1. Apenas enviamos os dados informados em txtEnviar.text

Acho que não falta mais nada . Epa , para fazer funcionar vamos incluir mais um formulário (frminicio) no projeto com dois botões de comandos : cmdServidor  e cmdCliente para que possamos abrir cada um dos módulos criados ai em cima. O jeitão e o código do formulário é o seguinte:

Private Sub cmdServidor_Click()
    frmservidor.Show
End Sub

Private Sub cmdCliente_Click()
   frmcliente.Show
End Sub

Para tornar o formulário frminicio o formulário que será executado primeiro ao rodar o projeto na opção Project|Properties  selecione como Start Object o formulário frminicio. Acabamos , só falta ver a coisa funcionar... Então...

  1. Execute o projeto : run ou F5
  2. Inicie o módulo Cliente e o módulo Servidor colocando as duas janelas lado a lado
  3. No módulo Cliente , informe o nome do computador e clique no botão Conectar
  4. Entre com algum texto na caixa de texto txtEnviar
  5. Clique no botão Enviar....Tchan Tchan Tchan ... Tchaaaaammmm
  6. Veja que o texto apareceu na caixa de texto txtReceber do módulo Servidor !!!!
  7. Agora no módulo Servidor , informe algum texto na caixa txtEnviar e clique no botão Enviar....
  8. Voilá,  ao texto aparece na caixa de texto txtReceber do Cliente.... Veja a figura abaixo

Nossa !!!  percebeu que estamos a um passo de um Chat... .A seguir nesta mesma bathora neste mesmo batcanal...

Criando o seu próprio Chat com Visual Basic

Já lançamos os fundamentos para que possamos criar um mini-chat com Visual Basic . A partir do momento que podemos enviar e receber mensagens na verdade já temos um chat bem rudimentar , vamos dar um melhorada no código e na interface para que a coisa fique com uma cara de chat...

Vamos ter que fazer uns ajustes , mas nada que seja muito complexo.  Continuaremos a trabalhar com dois módulos distintos : um cliente e outro servidor ; embora isto gerará uma redundância  de código , isto é , você vai perceber que o código do módulo servidor , será quase idêntico ao do módulo cliente. Assim acho que fica mais didático...  Vamos lá...

Vamos alterar a interface do módulo Cliente : Veja abaixo como vai ficar o formulário frmCliente :

Ao lado temos o formulário frmCliente já com o novo Layout do Chat.

-Aumentamos o tamanho do txtReceber mudando sua cor de fundo e as propriedades : Multiline , Locked , Backgroud e Font

-Incluimos a caixa de texto - txtnickname - onde você deve informar o nome que vai usar na conexão

-Criamos um Menu com duas opções : Limpar o chat ( txtreceber.text) e Sair do programa

-Incluimos uma etiqueta ( label ) com o nome de lblconexao que indicará o status da conexão.

- Aumentamos o tamanho de TxtEnviar 

Como funciona ?

Ao iniciar o módulo Cliente , a label -  lblconexao  - estará indicando o status de -  Não Conectado.  Ao clicar no botão - Conectar - a conexão estará ativa e a label irá indica o status de Conectado.

O texto será recebido pelo controle e exibido na caixa de texto Txtreceber , onde teremos discriminados , o nome de quem enviou a mensagem e a mensagem.

Para enviar a resposta , você vai usar a caixa de texto txtEnviar e clicar no botão Enviar

O código sofreu alguma alteração , e para não ficar repetindo , somente exibirei o código onde houve alteração: Assim , o código do botão foi alterado para : ( a alteração esta na cor vermelha )

Private Sub cmdEnviar_Click()
If txtEnviar.Text <> "" Then
    If wskCliente.State = sckConnected Then
         wskCliente.SendData txtnickname.Text & "-" & txtEnviar.Text
   
      Call Exibir_Mensagem_Chat(txtnickname.Text, txtEnviar.Text)
    Else
         If MsgBox("Você não esta conectado ainda . Deseja conectar a " & UCase(wskCliente.LocalHostName) & " ? ", vbYesNo + vbQuestion) = vbYes Then
             With wskCliente
             .Close
             .RemotePort = 100
             .RemoteHost = txtComputador.Text
             .Connect

             Do Until .State = sckConnected
                 DoEvents
                 If .State = sckError Then
                     MsgBox "Há problemas com a conexão !"
                     Exit Sub
                 End If
             Loop
            End With
        Else
            MsgBox "A conexão não foi realizada !", vbInformation, "Usando Winsock"
        End If
    End If
Else
    MsgBox "Informe a sua mensagem ! ", vbCritical, "Usando Winsock"
End If

End Sub

Verificamos se a mensagem a enviar e se a conexão está ok então enviamos a mensagem ( sendData ) e exibimos a mensagem na caixa de texto txtReceber. Para isto criamos a função - Exibir_Mensagem_Chat , abaixo

Private Sub Exibir_Mensagem_Chat(remetente As String, mensagem As String)
         TxtReceber.Text = TxtReceber.Text & " " & remetente & "- " & mensagem & vbCrLf
End Sub

A função irá receber o nome do remetente e a mensagem e irá atribuir estes valores a propriedade text da caixa de texto txtreceber. ( vbCrLf envia um Carriage Return e um Line Feed - assim o proximo texto será exibido na próxima linha)

No código do botão alterar , apenas incluímos o código que irá chamar a função - Exibir_Mensagem_Chat  . Temos :

Private Sub wskCliente_DataArrival(ByVal bytesTotal As Long)
  Dim strdados As String
  wskCliente.GetData strdados
 
Call Exibir_Mensagem_Chat("", strdados)
End Sub

No código do botão Conectar  , apenas incluímos o código que exibe o status de Conectado na label:

Private Sub cmdConectar_Click()
   wskCliente.RemoteHost = txtComputador.Text
   wskCliente.Connect
  
lblConexao.Caption = " Conectado "
End Sub

O código do módulo Servidor é praticamente idêntico ao do módulo cliente. Veja o novo layout do módulo servidor abaixo:

O código completo é o seguinte:

Private Sub cmdEnviar_Click()
If wskServidor.State = sckConnected Then
  wskServidor.SendData txtnickname & "-" & txtEnviar
  Call Exibir_Mensagem_Chat(txtnickname.Text, txtEnviar.Text)
Else
  MsgBox "Não existe conexão ativa , aguarde ... "
End If
End Sub

Private Sub Form_Load()

On Error GoTo trata_erro:

wskServidor.LocalPort = 100
wskServidor.Listen
Caption = " Winsock - Servidor - " & UCase(wskServidor.LocalHostName)
Exit Sub

trata_erro:
MsgBox " Outra aplicação esta usando a porta " & wskServidor.LocalPort, vbCritical, "Usando Winsock "
End
End Sub

Private Sub mnulimpachat_Click()
  txtReceber.Text = ""
End Sub

Private Sub mnusair_Click()
 Unload Me
End Sub

Private Sub wskServidor_ConnectionRequest(ByVal requestID As Long)
  If wskServidor.State <> sckClosed Then wskServidor.Close
  wskServidor.Accept requestID
End Sub

Private Sub wskServidor_DataArrival(ByVal bytesTotal As Long)
  Dim strdados As String
  wskServidor.GetData strdados
  Call Exibir_Mensagem_Chat("", strdados)
End Sub

Private Sub Exibir_Mensagem_Chat(remetente As String, mensagem As String)
   txtReceber.Text = txtReceber.Text & " " & remetente & "- " & " " & mensagem & vbCrLf
End Sub

Palavras finais:

-O projeto foi feito desta forma para poder mostrar em  uma máquina local a conexão com winsock mas você pode  criar um único formulário e escolher se quer se conectar como servidor ou como cliente. 

-Ao rodar duas instâncias do aplicativo poderá haver conflitos na definição da porta ( tente 202 ou 201). Para usar na internet basta informar o endereço IP do computador ao qual deseja conectar. ( winsock.remoteHost="127.0.0.1"). 

-Dica: Para pegar o IP você pode usar o ICQ quando o usuário se logar , ai voce pega o IP usando a propriedade LocalIP do winsock , armazena em um banco de dados e  depois , bem depois é com voce...

Creio que isto é tudo, por enquanto...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti