.NET - Usando a comunicação Cliente - Servidor com sockets


Antes do VB.NET para fazer uma comunicação cliente/servidor usando TCP/IP tínhamos que usar a biblioteca winsock, e  isto demandava muito código e a utilização de API´s.

O VB.NET fornece um conjunto de classes em System.Net.sockets que torna a nossa vida mais fácil , pois elas fornecem um conjunto de funcionalidades que abstraem muitas tarefas que antes exigiam a criação de código extra.

Antes de entrar na aplicação propriamente dita vamos recordar alguns conceitos básicos.

O que é um socket ?

Um socket pode ser entendido como uma porta de um canal de comunicação que permite a um processo executando em um computador enviar/receber mensagens para/de outro processo que pode estar sendo executado no mesmo computador ou num computador remoto.

Os sockets permitem então a comunicação processo a processo da seguinte forma :

Abaixo temos uma figura com que representa a comunicação de sockets e a pilha TCP/IP

Tipos de serviço de transporte:
  • Datagrama - transporte não orientado a conexão  e sem controle de erros ( protocolo UDP)
  • DataStream - transporte orientado a conexão com controle de erros ( protocolo TCP )

Paradigma cliente/servidor (modo orientado a conexão )

A seguir a seqüência de ações realizadas no paradigma cliente/servidor

Cliente Servidor
Cria um socket e atribui-lhe um endereço cria um socket e atribui-lhe um endereço. Este endereço deve ser conhecido pelo cliente.
Solicita a conexão do seu socket ao socket do servidor (conhece o endereço ) Aguarda a conexão de um cliente
Aguarda que a conexão seja estabelecida Aceita a conexão e cria um novo socket para comunicar com o cliente em causa
Envia uma mensagem ( request ) Recebe a mensagem no novo socket
Recebe a mensage de resposta (reply) Envia mensagem de resposta (reply)
Fecha a conexão com o servidor fecha a conexão com o cliente

Para colocar em prática a teoria vou criar dois projetos : TCPServidor e TCPCliente. Como não vou usar threads vamos precisar executar cada projeto separadamente. O projeto TCPServidor deverá ser executado primeiro e a seguir o projeto TCPCliente.

O projeto TCPServidor

Inicie um novo projeto no Visual Studio.NET com as seguintes características (sinta-se a vontade para alterar a seu gosto.)

  1. Project Types : Visual Basic Projects
  2. Templates : Windows Application
  3. Name : TCPServidor
  4. Location : c:\vbnet\TCPServidor

A seguir inclua o código abaixo no projeto. Nele estou executando o método Main() da classe TCPServidor. Como o método é estático eu não precisei instanciar um objeto para a classe. Ao ser executado o Servidor ficará aguardando por uma requisição de conexão.

Imports System.Net.Sockets
Imports System.Text

Module Module1

    Sub Main()
        TCPServidor.Main()
    End Sub

    Class TCPServidor

        Shared Sub Main()

            ' Precisa estar escutando na porta correta , tem que ser a mesma porta na qual o cliente vai usar
            Const numeroPorta As Integer = 8000
            Dim tcpListener As New TcpListener(numeroPorta)

            tcpListener.Start()

            Console.WriteLine("Aguardando uma conexão...")

            Try
                'aceita a conexao do cliente e retorna uma inicializacao TcpClient 
                Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
                Console.WriteLine("Conexão aceita.")

                ' obtem o stream
                Dim networkStream As NetworkStream = tcpClient.GetStream()

                ' le o stream em um array de bytes
                Dim bytes(tcpClient.ReceiveBufferSize) As Byte
                networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))

                ' Retorna os dados recebidos do cliente para o console
                Dim clientdata As String = Encoding.ASCII.GetString(bytes)
                Console.WriteLine(("Cliente enviou : " + clientdata))

                'qualquer comunicacao com o cliente remoto usando o TcpClient pode comecar aqui
                Dim responseString As String = "Conectado ao servidor."
                Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(responseString)
                networkStream.Write(sendBytes, 0, sendBytes.Length)
                Console.WriteLine(("Mensagem enviada /> : " + responseString))

                'fecha TcpListener e TcpClient.
                tcpClient.Close()
                tcpListener.Stop()
                Console.WriteLine("Encerrando conexão com o servidor")
                Console.ReadLine()
            Catch e As Exception
                Console.WriteLine(e.ToString())
                Console.ReadLine()
            End Try
        End Sub
    End Class


End Module

 

O projeto TCPCliente

Inicie um novo projeto no Visual Studio.NET com as seguintes características (sinta-se a vontade para alterar a seu gosto.)

  1. Project Types : Visual Basic Projects
  2. Templates : Windows Application
  3. Name : TCPCliente
  4. Location : c:\vbnet\TCPCliente

A seguir inclua o código abaixo no projeto. Nele estou executando o método Main() da classe TCPCliente. Como o método é estático eu não precisei instanciar um objeto para a classe. Ao ser executado o Cliente irá estabelecer uma conexão com o servidor na porta conhecida e enviará uma mensagem.

Imports System.Net.Sockets
Imports System.Text

Module Module1

    Sub Main()
        TCPCliente.Main()
    End Sub


    Class TCPCliente

        Shared Sub Main()
            Dim tcpClient As New System.Net.Sockets.TcpClient()
            Console.WriteLine("Estabelecendo conexão.")
            tcpClient.Connect("127.0.0.1", 8000)

            Dim networkStream As NetworkStream = tcpClient.GetStream()

            If networkStream.CanWrite And networkStream.CanRead Then
                ' executa apenas uma escrita
                Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes("Tem alguém ai ? ")
                networkStream.Write(sendBytes, 0, sendBytes.Length)

                ' Le o NetworkStream em um buffer
                Dim bytes(tcpClient.ReceiveBufferSize) As Byte
                networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))

                ' exibe os dados recebidos do host no console
                Dim returndata As String = Encoding.ASCII.GetString(bytes)
                Console.WriteLine(("Host retornou : " + returndata))
            Else
                If Not networkStream.CanRead Then
                    Console.WriteLine("Não é possível enviar dados para este stream")
                    tcpClient.Close()
                Else
                    If Not networkStream.CanWrite Then
                        Console.WriteLine("Não é possivel ler dados deste stream")
                        tcpClient.Close()
                    End If
                End If
            End If
            ' da uma pausa para pode ver o resultado
            Console.ReadLine()
        End Sub
    End Class


End Module

Execute o projeto TCPServidor teremos a janela do console exibindo a mensagem que o servidor esta aguardando uma mensagem:

A seguir executamos o projeto TCPCliente. Na figura abaixo temos que o cliente estabelece uma conexão com o servidor e a seguir envia uma mensagem.

A mensagem é recebida pelo servidor que a exibe e fecha a conexão.

Até o próximo artigo VB.NET... 

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