• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

zephirus

Comunicação Client-Server

11 mensagens neste tópico

Olá a todos.

O anterior tópico que abri tem um pouco a ver com esta questão mas de qualquer forma penso que é algo diferente.

Tendo eu duas aplicações em máquinas diferentes:

1- Servidor (10.40.30.30)

2- Cliente (10.40.30.40)

A aplicação Servidor tem uma listview e nessa máquina está também uma base de dados.

Na máquina cliente, a aplicação adiciona e retira items dessa base de dados da máquina servidor.

O que eu pretendo é: na máquina cliente fazer update da listview, ou aceder a essa listview. Como o posso fazer?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vamos la ver se não entendi mal. Pretendes dar uma instrução ao servidor para proceder ao update da listview?

Estas a dar essa instrução por tcp/ip?

Se sim..perfeitamente... basta teres um listener à espera de determinada instrução e depois criares codigp para fazer o update da listview.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vamos la ver se não entendi mal. Pretendes dar uma instrução ao servidor para proceder ao update da listview?

Estas a dar essa instrução por tcp/ip?

Se sim..perfeitamente... basta teres um listener à espera de determinada instrução e depois criares codigp para fazer o update da listview.

Sim, é isso. No cliente, ao modificar a base de dados, quero que a listview do servidor modifique também. E outra coisa, quando quero acrescentar algo na base de dados (no lado cliente), quero verificar antes alguns dados na listview do server. Vou pesquisar informação sobre o 'listener'...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

mas isto e uma solução de recurso... a base de dados..nao podia estar num unico local? é que nao me faz sentido estares a falar de servidor /cliente quando amboes têm Base de Dados e Aplicação..e parece-me a mim, para mostrar os mesmo dados.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Parei de pensar nesta questão mas voltando de novo à mesma...

- Neste momento estou a utilizar uma base de dados SQLite que tenho na máquina server (10.40.30.30). A minha aplicação cliente que está noutra máquina qualquer consegue escrever e ler para e dessa base de dados. O que eu pretendo agora, visto que a aplicação cliente vai ser usada em simultâneo por várias pessoas, é que quando alguém altera algo na base de dados, todas as aplicações clientes actualizem a informação.

Resumindo:

Cliente 1

Cliente 2

...

Cliente N

Quando o cliente 2, por exemplo, adiciona algo à base de dados, o cliente 1 e o cliente N são automaticamente actualizados.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só quero acrescentar uma coisa. Posso fazer isto de uma maneira simples, detectando apenas se o ficheiro da base de dados mudou de tamanho ou mudou a data ou hora. Quando qualquer uma dessas coisas acontecesse, actualizava os clientes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Os jogos MMORPG, como Ragnarok ou Lineage, são bons exemplos disso mesmo.

O único ponto que sabe que existem N clientes é o servidor, logo, se é efectuada uma alteração no cliente 2, esta é comunicada para o servidor que por sua vez comunica a alteração com todos os clientes, excepto o que a despoletou.

Nos jogos, as alterações são comunicadas até mesmo para o cliente que as causa para garantir a validação do servidor e a integridade dos dados sobre os clientes.

Mas isso aqui não têm importância uma vez que podes validar as introduções dos clientes. Não há perigo de arranjares um "exploit para chegares ao nível 99" :biggrin:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Descobri um exemplo numa procura pela net.

SERVER:

Imports System.Net.Sockets
Imports System.Text
Class TCPSrv
    Shared Sub Main()
        ' Must listen on correct port- must be same as port client wants to connect on.
        Const portNumber As Integer = 8000
        Dim tcpListener As New TcpListener(portNumber)
        tcpListener.Start()
        Console.WriteLine("Waiting for connection...")
        Try
            'Accept the pending client connection and return a TcpClient initialized for communication. 
            Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
            Console.WriteLine("Connection accepted.")
            ' Get the stream
            Dim networkStream As NetworkStream = tcpClient.GetStream()
            ' Read the stream into a byte array
            Dim bytes(tcpClient.ReceiveBufferSize) As Byte
            networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
            ' Return the data received from the client to the console.
            Dim clientdata As String = Encoding.ASCII.GetString(bytes)
            Console.WriteLine(("Client sent: " + clientdata))
            Dim responseString As String = "Connected to server."
            Dim sendBytes As [byte]() = Encoding.ASCII.GetBytes(responseString)
            networkStream.Write(sendBytes, 0, sendBytes.Length)
            Console.WriteLine(("Message Sent /> : " + responseString))
            'Any communication with the remote client using the TcpClient can go here.
            'Close TcpListener and TcpClient.
            tcpClient.Close()
            tcpListener.Stop()
            Console.WriteLine("exit")
            Console.ReadLine()
        Catch e As Exception
            Console.WriteLine(e.ToString())
            Console.ReadLine()
        End Try
    End Sub
End Class

Queria "transformar" este código de modo a usá-lo numa form com um botão para fazer o start do listening, um label para mostrar o "Waiting for connection...". Não estou a conseguir fazê-lo. A partir do momento em que é executado o comando tcpListener.Start(), o programa parece encravado.

Alguém pode ajudar?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Coloca esse código dentro de um BackgroundWorker e no botão colocas BackgroundWorker.RunWorkerAsync()

Mas lembra-te, com o BackgroundWorker, para mandares info para fora dele terás que usar o método ProgressChanged por exemplo assim:

Nota: O BackgroundWorker terá de ter a propriedade WorkerReportsProgress = True

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
bkgServer.RunWorkerAsync()
End Sub

Private Sub bkgServer_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bkgServer.DoWork
' Must listen on correct port- must be same as port client wants to connect on.
        Const portNumber As Integer = 8000
        Dim tcpListener As New TcpListener(portNumber)
        tcpListener.Start()
        Me.Label1.Text = "Waiting for connection..."
        Try
            'Accept the pending client connection and return a TcpClient initialized for communication.
            Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
            Me.Label1.Text = "Connection accepted."
            ' Get the stream
            Dim networkStream As NetworkStream = tcpClient.GetStream()
            ' Read the stream into a byte array
            Dim bytes(tcpClient.ReceiveBufferSize) As Byte
            networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
            ' Return the data received from the client to the console.
            Dim clientdata As String = Encoding.ASCII.GetString(bytes)
          
            Dim responseString As String = "Connected to server."
            Dim sendBytes As [byte]() = Encoding.ASCII.GetBytes(responseString)
            networkStream.Write(sendBytes, 0, sendBytes.Length)
            'Console.WriteLine(("Message Sent /> : " + responseString))  PENSO QUE NÃO NECESSITAS DISTO NESTE CASO
            bkgServer.ReportProgress(100, ("Client sent: " + clientdata))
            'Any communication with the remote client using the TcpClient can go here.
            'Close TcpListener and TcpClient.
            tcpClient.Close()
            tcpListener.Stop()
            Catch e As Exception
            MsgBox(e.ToString())
        End Try
End Sub

Private Sub bkgServer_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bkgServer.ProgressChanged
'AQUI FAZES O QUE QUIZERES COM A INFO RECEBIDA PELO SOCKET 
        MsgBox(e.UserState)
End Sub

Private Sub bkgServer_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bkgServer.RunWorkerCompleted
'ISTO SERVE PARA QUE O TEU SOCKET SE LIGUE APÓS RECEBER INFO E TER TERMINADO.
        bkgServer.RunWorkerAsync()
End Sub

Penso que não me esqueci de nada.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Obrigado Weasel. Assim que possa vou dar uma olhada e testar o teu código.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora