VB6 - P2P - Peer to Peer Networking com o controle Winsock
Na certa você já ouviu o termo - Peer to Peer - (daqui pra frente apenas P2P). Já ouviu falar no Napster e mais recentemente no Kazaa ???? Pois é , esses e muitos outros programas funcionam baseados no P2P , que nada mais é que um modelo de rede PC para PC onde você faz a comunicação entre dois PC´s em uma rede TCP/IP. (A internet é uma rede TCP/IP).
Como na internet existem milhões de PC´s que podem fazer o papel de cliente como de servidor temos o cenário ideal para explorar o modelo P2P e , neste artigo eu vou mostrar como usar o controle Winsock do Visual Basic para realizar a comunicação entre dois PC´s em uma rede TCP/IP.
Para você saber mais sobre o controle Winsock leia os artigos já publicados neste site em :
Como já falei das propriedades do controle Winsock nos artigos acima vou direto ao que interessa : a aplicação P2P.
Criando seu aplicativo P2P
Teremos na verdade dois aplicativos e por consequência dois projetos : um que fará o papel de cliente e outro que fará o papel de servidor.Nosso objetivo é trocar arquivos entre os dois PC´s semelhante ao que você faz quando baixa uma música usando o Kazaa...
O projeto Servidor
Antes de qualquer iniciativa você deve incluir no seu projeto o componente Winsock. No menu Project|Components selecione : Microsoft Winsock Control X.0 (onde x é a versão do seu controle. Eu estou usando a 6.0)
No evento General Declarations do formulário padrão vamos inserir o seguinte código :
Option
Explicit Dim lPos As Long Dim bOK As Boolean Dim fnome As String |
Ne definimos as variáveis que serão visivéis no formulário |
Crie um novo projeto no Visual Basic do tipo Standard EXE e no formulário padrão insira os controles conforme layout abaixo:
Chamei o projeto de - p2pServidor.vbp
, o formulário de frmservidor
e dei o nome de wsTCP
ao controle Winsock inserido no formulário. - Estou usando os DriveListBox - Dir1 , DirListBox - Dir1 e FileListBox - File1 . Para exibir os drives , diretórios e arquivos do sistema. O sincronismo entre os controles é feito pelo código abaixo associado ao evento Change de cada controle.
|
Nota : Se você executar o projeto agora e a seguir executar o comando Netstat -a vai obter:
-Perceba que a estamos usando o protocolo TCP e que a porta 2000 no host - macorati tem seu estado em LISTENING. |
No evento Click do botão de comando - Ativar Servidor- insira o seguinte código:
Private
Sub cmdAtivar_Click() If cmdAtivar.Caption = "Ativar Servidor" Then cmdAtivar.Caption = "Parar Servidor" wsTCP(0).LocalPort = 2000 wsTCP(0).Listen Else wsTCP(0).Close cmdAtivar.Caption = "Ativar Servidor" End If End Sub |
- O código apenas define a porta na qual o servidor vai estar escutando |
Código do evento ConnectionRequest do controle Winsock no formulário - frmservidor:
Private
Sub wsTCP_ConnectionRequest(Index As Integer, ByVal
requestID As Long) Load wsTCP(1) If wsTCP(1).State <> sckClosed Then wsTCP(1).Close wsTCP(1).Accept requestID End Sub |
- Verificamos o estado
do controle, se ele não estiver fechado devemos
fechá-lo. Os principais valores possíveis para a propriedade State são:
- O Método Accept aceita a conexão |
Quando os dados estiverem chegando o evento DataArrival é disparado , nele inserimos o seguinte código:
Private
Sub wsTCP_DataArrival(Index As Integer, ByVal bytesTotal
As Long) If Not bOK Then wsTCP(1).GetData fnome If InStr(fnome, vbCrLf) <> 0 Then fnome = Left(fnome, InStr(fnome, vbCrLf) - 1) bOK = True If Dir(Dir1.Path & "\" & fnome) <> "" Then Kill Dir1.Path & "\" & fnome Open Dir1.Path & "\" & fnome For Binary As 1 lPos = 1 wsTCP(1).SendData "OK" & vbCrLf Else Dim buffer() As Byte wsTCP(1).GetData buffer Put #1, lPos, buffer lPos = lPos + UBound(buffer) + 1 End If End Sub |
- O método GetData Efetua a recepção do arquivo
fnome. - Extraimos o nome do arquivo e colocamos os dados em um buffer. |
Para encerrar a conexão usamos o código abaixo no evento Close:
Private
Sub wsTCP_Close(Index As Integer) Close #1 Unload wsTCP(1) bOK = False End Sub |
O projeto Cliente
Para cria o projeto cliente siga as mesmas etapas iniciais usadas no projeto servidor:
O nome do projeto cliente será : p2pCliente.vbp e o formulário será chamado de frmcliente.
- Além do controle
winsock estou usando o controle CommonDialog
- dlg - para buscar um arquivo para ser enviado. Na seção General Declarations do forma declaramos as variáveis que serão visíveis no formulário:
|
O usuário deverá selecionar um arquivo para enviar para o servidor clicando no botão - cmdBusca - cujo código é o seguinte:
Private
Sub cmdBusca_Click() dlg.ShowOpen txtArquivo.Text = dlg.FileName End Sub |
Após a seleção basta clicar no botão - Enviar Arquivo para o Servidor . O seu código é dado abaixo:
Private
Sub cmdEnvia_Click() cmdEnvia.Enabled = False lBytes = 0 ReDim buffer(FileLen(dlg.FileName) - 1) Open dlg.FileName For Binary As 1 Get #1, 1, buffer Close #1 Load wsTCP(1) wsTCP(1).RemoteHost = "127.0.0.1" wsTCP(1).RemotePort = 2000 wsTCP(1).Connect lblStatus.Caption = "Conectando..." End Sub |
-
Criamos um buffer do tamanho do arquivo - abrimos o arquivo selecionado no modo binário - Pegamos os dados do buffer - Definimos o computador
para onde iremos enviar o arquivo. Como eu estou na
máquina local usamos o número - Efetuamos a conexão |
- no evento Connect - indicamos a conexão e enviamos os dados | Private
Sub wsTCP_Connect(Index As Integer) lblStatus = "Conectado !" wsTCP(1).SendData dlg.FileTitle & vbCrLf End Sub |
No evento DataArrival - temos o seguinte código:
Private
Sub wsTCP_DataArrival(Index As Integer, ByVal bytesTotal
As Long) wsTCP(1).GetData temp If InStr(temp, vbCrLf) <> 0 Then temp = Left(temp, InStr(temp, vbCrLf) - 1) If temp = "OK" Then wsTCP(1).SendData buffer Else lblStatus.Caption = "Ocorreu um problema durante a recepção..." Unload wsTCP(1) cmdEnvia.Enabled = True End If End Sub |
No evento SendProgress - indicamos a progressão da remessa do arquivo:
Private
Sub wsTCP_SendProgress(Index As Integer, ByVal bytesSent
As Long, ByVal bytesRemaining As Long) If temp = "OK" Then lBytes = lBytes + bytesSent lblStatus = lBytes & " de um total de " & UBound(buffer) & " bytes enviados" End If End Sub |
No evento SendComplete - Informamos que a remessa de dados terminou e habilitamos o botão para uma nova transmissão:
Private
Sub wsTCP_SendComplete(Index As Integer) If temp = "OK" Then lblStatus.Caption = "Remessa do arquivo completada com sucesso !" temp = "" Unload wsTCP(1) cmdEnvia.Enabled = True End If End Sub |
Para encerrar a conexão usamos o evento Close:
Private
Sub wsTCP_Close(Index As Integer) lblStatus.Caption = "Conexão fechada..." Unload wsTCP(1) End Sub |
Agora só falta testar o projeto . Para isto carregue o projeto p2pServidor.vbp em uma instância e o projeto p2pCliente.vbp em outra instância:
- Inicie o projeto p2pServidor.vbp e clique no botão para ativar o servidor . A seguir selecione um diretório para onde deseja receber os arquivos que serão transferidos.
- A seguir inicie o projeto p2pCliente.vbp e selecione um arquivo e depois clique no botão - Enviar Arquivo para o Servidor.
Na figura acima temos uma ilustração do projeto em execução. Se o teste for feito em uma máquina local a transferência deve ser bem rápida.
Pronto ! Você já tem o esquelo de seu projeto P2P cabe a você incrementar a interface e os recursos (e o código) ...
José Carlos Macoratti