none
Utilización de Cliente/Servidor RRS feed

  • Pregunta

  • Buenas tardes, tengo dos clases, una de cliente y otra de servidor:

    Servidor:

    Imports System.Net.Sockets
    Imports System.Threading
    Imports System.Text
    
    Public Class WinSockServer
    
    
    
    #Region "ESTRUCTURAS"
        Private Structure InfoDeUnCliente
            'Esta estructura permite guardar la información sobre un cliente
            Public Socket As Socket 'Socket utilizado para mantener la conexion con el cliente
            Public Thread As Thread 'Thread utilizado para escuchar al cliente
            Public UltimosDatosRecibidos As String 'Ultimos datos enviados por el cliente
        End Structure
    
    #End Region
    
    #Region "VARIABLES"
        Private tcpLsn As TcpListener
        Private Clientes As New Hashtable() 'Aqui se guarda la informacion de todos los clientes conectados
        Private tcpThd As Thread
        Private IDClienteActual As Net.IPEndPoint 'Ultimo cliente conectado
        Private m_PuertoDeEscucha As String
    #End Region
    
    #Region "EVENTOS"
        Public Event NuevaConexion(ByVal IDTerminal As Net.IPEndPoint)
        Public Event DatosRecibidos(ByVal IDTerminal As Net.IPEndPoint)
        Public Event ConexionTerminada(ByVal IDTerminal As Net.IPEndPoint)
    #End Region
    
    #Region "PROPIEDADES"
        Property PuertoDeEscucha() As String
            Get
                PuertoDeEscucha = m_PuertoDeEscucha
            End Get
            Set(ByVal Value As String)
                m_PuertoDeEscucha = Value
            End Set
        End Property
    #End Region
    
    #Region "METODOS"
        Public Sub Escuchar()
            tcpLsn = New TcpListener(8050)
            'Inicio la escucha
            tcpLsn.Start()
            'Creo un thread para que se quede escuchando la llegada de un cliente
            tcpThd = New Thread(AddressOf EsperarCliente)
            tcpThd.Start()
        End Sub
        Public Function ObtenerDatos(ByVal IDCliente As Net.IPEndPoint) As String
            Dim InfoClienteSolicitado As InfoDeUnCliente
            'Obtengo la informacion del cliente solicitado
            InfoClienteSolicitado = Clientes(IDCliente)
            ObtenerDatos = InfoClienteSolicitado.UltimosDatosRecibidos
        End Function
        Public Sub Cerrar(ByVal IDCliente As Net.IPEndPoint)
            Dim InfoClienteActual As InfoDeUnCliente
            'Obtengo la informacion del cliente solicitado
            InfoClienteActual = Clientes(IDCliente)
            'Cierro la conexion con el cliente
            InfoClienteActual.Socket.Close()
        End Sub
        Public Sub Cerrar()
            Dim InfoClienteActual As InfoDeUnCliente
            'Recorro todos los clientes y voy cerrando las conexiones
            For Each InfoClienteActual In Clientes.Values
                Call Cerrar(InfoClienteActual.Socket.RemoteEndPoint)
            Next
        End Sub
        Public Sub EnviarDatos(ByVal IDCliente As Net.IPEndPoint, ByVal Datos As String)
            Dim Cliente As InfoDeUnCliente
            'Obtengo la informacion del cliente al que se le quiere enviar el mensaje
            Cliente = Clientes(IDCliente)
            'Le envio el mensaje
            Cliente.Socket.Send(Encoding.ASCII.GetBytes(Datos))
        End Sub
        Public Sub EnviarDatos(ByVal Datos As String)
            Dim Cliente As InfoDeUnCliente
            'Recorro todos los clientes conectados, y les envio el mensaje recibido
            'en el parametro Datos
            For Each Cliente In Clientes.Values
                EnviarDatos(Cliente.Socket.RemoteEndPoint, Datos)
            Next
        End Sub
    #End Region
    
    #Region "FUNCIONES PRIVADAS"
        Private Sub EsperarCliente()
            Dim InfoClienteActual As InfoDeUnCliente
            With InfoClienteActual
                While True
                    'Cuando se recibe la conexion, guardo la informacion del cliente
                    'Guardo el Socket que utilizo para mantener la conexion con el cliente
                    .Socket = tcpLsn.AcceptSocket() 'Se queda esperando la conexion de un cliente
                    'Guardo el el RemoteEndPoint, que utilizo para identificar al cliente
                    IDClienteActual = .Socket.RemoteEndPoint
                    'Creo un Thread para que se encargue de escuchar los mensaje del cliente
                    .Thread = New Thread(AddressOf LeerSocket)
                    'Agrego la informacion del cliente al HashArray Clientes, donde esta la
                    'informacion de todos estos
                    SyncLock Me
                        Clientes.Add(IDClienteActual, InfoClienteActual)
                    End SyncLock
                    'Genero el evento Nueva conexion
                    RaiseEvent NuevaConexion(IDClienteActual)
                    'Inicio el thread encargado de escuchar los mensajes del cliente
                    .Thread.Start()
                End While
            End With
        End Sub
    
        Private Sub LeerSocket()
            Dim IDReal As Net.IPEndPoint 'ID del cliente que se va a escuchar
            Dim Recibir() As Byte 'Array utilizado para recibir los datos que llegan
            Dim InfoClienteActual As InfoDeUnCliente 'Informacion del cliente que se va escuchar
            Dim Ret As Integer = 0
            IDReal = IDClienteActual
            InfoClienteActual = Clientes(IDReal)
            With InfoClienteActual
                While True
                    If .Socket.Connected Then
                        Recibir = New Byte(100) {}
                        Try
                            'Me quedo esperando a que llegue un mensaje desde el cliente
                            Ret = .Socket.Receive(Recibir, Recibir.Length, SocketFlags.None)
                            If Ret > 0 Then
                                'Guardo el mensaje recibido
                                .UltimosDatosRecibidos = Encoding.ASCII.GetString(Recibir)
                                Clientes(IDReal) = InfoClienteActual
                                'Genero el evento de la recepcion del mensaje
                                RaiseEvent DatosRecibidos(IDReal)
                            Else
                                'Genero el evento de la finalizacion de la conexion
                                RaiseEvent ConexionTerminada(IDReal)
                                Exit While
                            End If
                        Catch e As Exception
                            If Not .Socket.Connected Then
                                'Genero el evento de la finalizacion de la conexion
                                RaiseEvent ConexionTerminada(IDReal)
                                Exit While
                            End If
                        End Try
                    End If
                End While
                Call CerrarThread(IDReal)
            End With
        End Sub
        Private Sub CerrarThread(ByVal IDCliente As Net.IPEndPoint)
            Dim InfoClienteActual As InfoDeUnCliente
            'Cierro el thread que se encargaba de escuchar al cliente especificado
            InfoClienteActual = Clientes(IDCliente)
            Try
                InfoClienteActual.Thread.Abort()
            Catch e As Exception
                SyncLock Me
                    'Elimino el cliente del HashArray que guarda la informacion de los clientes
                    Clientes.Remove(IDCliente)
                End SyncLock
            End Try
        End Sub
    #End Region
    
    
    
    End Class

    Cliente:

    Imports System.IO
    Imports System.Net.Sockets
    Imports System.Threading
    Imports System.Text
    
    Public Class Cliente
    
    #Region "VARIABLES"
        Private Stm As Stream 'Utilizado para enviar datos al Servidor y recibir datos del mismo
        Private m_IPDelHost As String 'Direccion del objeto de la clase Servidor
        Private m_PuertoDelHost As String 'Puerto donde escucha el objeto de la clase Servidor
    #End Region
    
    #Region "EVENTOS"
        Public Event ConexionTerminada()
        Public Event DatosRecibidos(ByVal datos As String)
    #End Region
    
    #Region "PROPIEDADES"
        Public Property IPDelHost() As String
            Get
                IPDelHost = m_IPDelHost
            End Get
            Set(ByVal Value As String)
                m_IPDelHost = Value
            End Set
        End Property
    
    
    
        Public Property PuertoDelHost() As String
    
            Get
    
                PuertoDelHost = m_PuertoDelHost
    
            End Get
    
            Set(ByVal Value As String)
    
                m_PuertoDelHost = Value
    
            End Set
    
        End Property
    
    #End Region
    
    #Region "METODOS"
        Public Sub Conectar()
            Dim tcpClnt As TcpClient
            Dim tcpThd As Thread 'Se encarga de escuchar mensajes enviados por el Servidor
            tcpClnt = New TcpClient()
            'Me conecto al objeto de la clase Servidor,
            'determinado por las propiedades IPDelHost y PuertoDelHost
            tcpClnt.Connect(IPDelHost, PuertoDelHost)
            Stm = tcpClnt.GetStream()
            'Creo e inicio un thread para que escuche los mensajes enviados por el Servidor
            tcpThd = New Thread(AddressOf LeerSocket)
            tcpThd.Start()
        End Sub
    
        Public Sub EnviarDatos(ByVal Datos As String)
            Dim BufferDeEscritura() As Byte
            BufferDeEscritura = Encoding.ASCII.GetBytes(Datos)
            If Not (Stm Is Nothing) Then
                'Envio los datos al Servidor
                Stm.Write(BufferDeEscritura, 0, BufferDeEscritura.Length)
            End If
        End Sub
    #End Region
    
    #Region "FUNCIONES PRIVADAS"
        Private Sub LeerSocket()
            Dim BufferDeLectura() As Byte
    
            While True
                Try
                    BufferDeLectura = New Byte(100) {}
                    'Me quedo esperando a que llegue algun mensaje
                    Stm.Read(BufferDeLectura, 0, BufferDeLectura.Length)
                    'Genero el evento DatosRecibidos, ya que se han recibido datos desde el Servidor
                    RaiseEvent DatosRecibidos(Encoding.ASCII.GetString(BufferDeLectura))
                Catch e As Exception
                    Exit While
                End Try
            End While
            'Finalizo la conexion, por lo tanto genero el evento correspondiente
            RaiseEvent ConexionTerminada()
        End Sub
    #End Region

    Lo que quiero es que cuando los clientes reciban un determinado numero actualicen su DataGridView:

     Private Sub WinSockCliente_DatosRecibidos(ByVal dato As String) Handles WinSockCliente.DatosRecibidos
            If dato = 1 Then
                Me.FVTableAdapter.Fill(Me.DataSet1.FV)
            End If
        End Sub

    Lo que ocurre es que no pasa nada, alguna solucion?

    • Cambiado Enrique M. Montejo jueves, 15 de junio de 2017 6:02 Pregunta relacionada con controles de Windows Forms.
    viernes, 9 de junio de 2017 21:04

Todas las respuestas

  • Me da un error aquí

    tcpLsn = New TcpListener(8050)

    Prueba cambiando  a

    tcpLsn = New TcpListener(IPAddress.Parse("127.0.0.1"), 8050)

    Importando System.Net y System.IO en ambos (Servidor y Clilente)

    viernes, 9 de junio de 2017 22:45
  • Me da un error aquí

    tcpLsn = New TcpListener(8050)

    Prueba cambiando  a

    tcpLsn = New TcpListener(IPAddress.Parse("127.0.0.1"), 8050)

    Importando System.Net y System.IO en ambos (Servidor y Clilente)

    Gracias por responder. Es solo una advertencia, funciona igual.

    De esa manera igual sigue sin pasar nada, no me actualiza la grilla. Si actualizo la grilla en el Load si lo hace correctamente.

    viernes, 9 de junio de 2017 22:50
  • Bueno pero entonces si funciona, lo que hay que revisar es el llamado desde el Form
    sábado, 10 de junio de 2017 1:58
  • Bueno pero entonces si funciona, lo que hay que revisar es el llamado desde el Form

    si  hago :

    Private Sub WinSockCliente_DatosRecibidos(ByVal dato As String) Handles WinSockCliente.DatosRecibidos
            If dato = 1 Then
                msgbox("HOLA")
            End If
        End Sub
    Funciona, llamadas a funciones no


    sábado, 10 de junio de 2017 2:46
  • Hola @JoniJeJ

    Te sugiero que le des una leída a este link que te comparto AYUDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    Así te podemos dar una solución mas rápida.

    Saludos


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú


    sábado, 10 de junio de 2017 3:19
  • Hola @Pedro Ávila

    que es lo que no se entiende? mostre las 2 clases que estoy usando, y el problema; que cuando los clientes reciben un numero no actualizan su datagridview

    sábado, 10 de junio de 2017 14:41