Como puedo elaborar esta idea ?

Iniciado por TrashAmbishion, 23 Julio 2016, 00:22 AM

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

TrashAmbishion

Hola,

Amigos tengo una aplicación cliente/servidor, cuando un cliente se conecta tengo un ListBox al que añado la ip del cliente, pero esto necesito modificarlo y mostrar el nombre del cliente, esto lo puedo hacer sin problemas el tema es que tengo una opción para desconectar a un cliente y necesito pasarle como parámetro la ip de dicho cliente que sacaba del ListBox pero si en vez de añadir la ip añado el nombre al Listbox ya tendría que ingeniar otra forma.

Como podría solucionar esto.

Salu2 y gracias de antemano !!

Eleкtro

#1
Cita de: TrashAmbishion en 23 Julio 2016, 00:22 AMComo podría solucionar esto.

Simplemente crea un type para almacenar el nombre y la ip, y en el listbox muestras uno de esos dos datos almacenados:

Código (vbnet) [Seleccionar]
Public Class ClientInfo

   Public ReadOnly Property Ip As String
   Public ReadOnly Property Name As String

   Private Sub New()
   End Sub

   Public Sub New(ip As String, name As String)
        Me.Ip = ip
        Me.name  = name
   End Sub

End Class


Código (vbnet) [Seleccionar]
Dim clients As New List(Of ClientInfo)
clients.Add(New ClientInfo("255.255.255.255", "Elektro"))
clients.Add(...)

For Each client As ClientInfo In clients
   ListBox1.Add(client.Name)
Next


Obtener ip por nombre:
Código (vbnet) [Seleccionar]
Dim ip As String = (From client As ClientInfo In clients Where client.Name.Equals("Elektro")).Single()

Otra forma de elaborar la idea, sobre todo la obtención de la ip, sería crear/heredar una colección y añadir un indexer que tome un nombre, es más cool pero es un ejemplo algo costoso de escribir y con eso que te puse arriba con LINQ consigues lo mismo.

Saludos








TrashAmbishion

Gracias voy a implementarlo.

PD: Cuando desconecte a un cliente evidentemente tengo que retirarlo del List, supongo que llamando al metodo:


Código (vbnet) [Seleccionar]
clients.remove

Salu2

TrashAmbishion

Me dice en la línea

Código (vbnet) [Seleccionar]
    Dim ip As String = (From client As ClientInfo In clients Where client.Name.Equals("Elektro")).Single()

Que no puede convertir el valor de ClientInfo a String

Salu2

TrashAmbishion

Necesito pasar una estructura:

Usuario
Contraseña
Ip

Pudiera usar la misma idea, verdad?

La duda que tengo y me tiene pensativo es como paso esa estructura de una forma no muy rebuscada (para futuro entendimiento) hacia la otra aplicación y esta la pueda utilizar sin mucha complicación.

Salu2 y gracias de antemano

Eleкtro

#5
Cita de: TrashAmbishion en  5 Agosto 2016, 06:59 AM
Necesito pasar una estructura:

Usuario
Contraseña
Ip

Pudiera usar la misma idea, verdad?

Por supuesto, la idea que te mostré arriba la puedes implementar con la cantidad de campos que desees. Por otro lado, si por "estructura" también te estás refiriendo a utilizar el tipo Structure, entonces debes tener en cuenta la cantidad de campos que definas, o mejor dicho el tamaño de la estructura, y si los campos se pasan por valor o por referencia.




Cita de: TrashAmbishion en  5 Agosto 2016, 06:59 AMLa duda que tengo y me tiene pensativo es como paso esa estructura de una forma no muy rebuscada (para futuro entendimiento) hacia la otra aplicación y esta la pueda utilizar sin mucha complicación.

Tienes varias opciones para la comunicación entre procesos, pero ya que tu aplicación se basa en el uso de Sockets, entonces lo más directo sería aprovecharte de una metodología basada en Sockets, por ejemplo creando un NetworkStream basado en un Socket.

Teniendo una class como esta de aquí abajo definida tanto en la app cliente como en la app servidor, tienes a tu disposición varias alternativas para llevar a cabo lo mismo (la conversión de tipos):
Código (vbnet) [Seleccionar]
Public NotInheritable Class ClientInfo

   Public ReadOnly Property UserName As String
   Public ReadOnly Property Password As String
   Public ReadOnly Property IpAddress As String

   Private Sub New()
   End Sub

   Public Sub New(ByVal userName As String,
                  ByVal password As String,
                  ByVal ipAddress As String)

       Me.UserName = userName
       Me.Password = password
       Me.IpAddress = ipAddress

   End Sub

   Public Function ToStream() As Stream
       Dim ms As New MemoryStream()

       Using writer As New BinaryWriter(ms, Encoding.Default, leaveOpen:=True)
           With writer
               .Write(3) ' Cantidad de valores.
               .Write(Me.UserName)
               .Write(Me.Password)
               .Write(Me.IpAddress)
           End With
       End Using

       ms.Seek(0, SeekOrigin.Begin)
       Return ms
   End Function

   Public Shared Function FromStream(ByVal sr As Stream) As ClientInfo

       Using reader As New BinaryReader(sr, Encoding.Default, leaveOpen:=True)
           Dim count As Integer = reader.ReadInt32()
           Dim list As New List(Of String)(count)

           For x As Integer = 0 To (count - 1)
               list.Add(reader.ReadString())
           Next x
           sr.Seek(0, SeekOrigin.Begin)

           Return New ClientInfo(username:=list(0), password:=list(1), ipAddress:=list(2))
       End Using

   End Function

   Public Overloads Shared Widening Operator CType(ByVal sender As Stream) As ClientInfo
       Return ClientInfo.FromStream(sender)
   End Operator

   Public Overloads Shared Widening Operator CType(ByVal sender As ClientInfo) As Stream
       Return sender.ToStream()
   End Operator

   Public Overloads Function ToString() As String
       Return String.Format("{0};{1};{2}", Me.UserName, Me.Password, Me.IpAddress)
   End Function

End Class


Ejemplo:
Código (vbnet) [Seleccionar]
Dim ci As New ClientInfo("Elektro", "Contraseña", "255.255.255.255")
Dim clientSocket As Socket = ...
Dim netStream As New NetworkStream(clientSocket, ownsSocket:=True)

Using sr As Stream = ci.ToStream()
   sr.CopyTo(netStream)
End Using


Código (vbnet) [Seleccionar]
Dim ci As ClientInfo = ClientInfo.FromStream(netStream)

Hay varias maneras de hacerlo, también podrías especificar el tamaño de cada string en los primeros bytes para parsearlo de otra manera, como a ti te resulte mejor. O incluso puedes recurrir a técnicas de marshalling con estructuras de un tamaño fijo definido, pero eso lo veo innecesario, rebuscado y sobretodo tedioso.

Lo cierto es que no lo he testeado en profundidad usando un socket, pero espero que esa class y el ejemplo te sirva para hacerte una idea, si sigues teniendo dudas o no te convence esa metodología entonces puedes probar otras:

Saludos!








TrashAmbishion

Muchas gracias lo analizaré y acomodaré.

Thx a lot..


TrashAmbishion

El código esta perfecto lo que sucede es que no lo he podido implementar del todo por que hay cosas que no comprendo bien y no logro adaptarlo al proyecto que estoy usando como base.

El codigo que tengo envia asi:

Código (vbnet) [Seleccionar]
_socket.Send(textSend.Text)

Mi pregunta hay alguna forma de mandar el tipo ClientInfo usando esta opción y poderlo recibir en el Servidor para hacer una comparación con los usuarios registrados.