Consulta Sockets en VB .NET

Iniciado por martus444, 2 Julio 2013, 21:49 PM

0 Miembros y 1 Visitante están viendo este tema.

martus444

Hola gente buenas tardes, estoy haciendo un programa en VB.net, este programa se trata de un cliente y un server conectandose con la utilizacion de sockets y simulando un chat, tengo una problematica ya que estoy conectandome con mi maquina como cliente y enviando mensajes de un server a un cliente correctamente, ahora necesito saber como enviar de un server a varios clientes!!! No se como volver a conectar otro cliente, no me sale este punto!!! Adjunto codigo para que lo vean si son tan amables de poder ayudarme!!!!

Muchas gracias!!!!

Codigo de la clase server:


Imports System

Imports System.Threading

Imports System.Net.Sockets

Imports System.IO

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(PuertoDeEscucha)

        '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


Código de la clase Cliente

Imports System

Imports System.Net

Imports System.Net.Sockets

Imports System.Threading

Imports System.Text

Imports System.IO



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



End Class

kub0x

El servidor debe de tener una lista de clientes conectados a éste para poder enviarles los datos especificados. Si lo que quieres es crear un chat, pues, la dinámica a seguir es sencilla: Los clientes se conectan al server, le envian datos (mensajes) y el server responde a todos los clientes conectados en ese mismo momento con el mensaje recibido.

Cliente -> envía mensaje al server -> server responde a todos los usuarios. Para conectar más de un cliente al servidor, pues, ejecuta tu cliente varias veces y asegúrate de que tu servidor soporta más de un cliente.

Bueno supongo que estás aprendiendo, pero será por gustos, sin embargo no me gusta realizar implementaciones empleando las clases TcpClient y TcpListener, apuesto por Socket.

Saludos y tus dudas son bien recibidas.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate