Estructura Perruna - ¿Donde falla?

Iniciado por Kasi, 31 Julio 2009, 18:58 PM

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

Kasi

Muy buenas a todos, hace algún tiempo que empecé a diseñar una aplicación que tiene una pequeña estructura donde guardo información.
Para guardar todas las instancias de la estructura utilizo un HashTable donde agrego cada instancia.
HashTable(Id,Nombre de la Instancia)

El problema viene que a medida que voy generando instancias de esa estructura y rellenandolas, en principio todo funciona perfectamente, la primera vez que intento recuperar datos de alguna instancia los recupera bien, pero si los intento recuperar una segunda vez por ejemplo, de una instancia que ya he consultado antes, no contiene nada...solo devuelve correctamente el thread que la maneja, pero de las variables que almacenan datos(strings y demas...) no obtiene nada.He revisado el código de arriba a abajo por si en algun momento hago algo que pueda sobreescribir la instancia dentro del HashTable, pero nada.

¿Alguien sabe a que puede deberse? Ya no me quedan mas ideas para probar x_X

Saludos y gracias.

Novlucker

Lenguaje? Así como así no se me ocurre ... sería bueno que dejes el code o fragmento de code donde ocurre esto  :-\

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Kasi

El lenguaje que estoy usando es VB.Net, dejo un par de trozos donde relleno la estructura por primera vez, y donde la completo posteriormente, asi como un trozo donde la uso para obtener la información.

Esta es la estructura.

        Public Structure InfoCliente
        Public Socket As Socket 'Socket por cada cliente
        Public Thread As Thread 'Thread utilizado para el cliente
        Public DatosRecibidos As String 'Datos que el cliente nos envia
        Public Ip As String 'La dirección del cliente
        Public Nombre As String ' Nombre
        Public Status As String  'Para conocer si el cliente esta utilizando la aplicación
        Public Manager As ClientManager ' Formulario donde podemos consultar información del cliente.


Luego cuando recibo la conexión de algun cliente hago:


.Socket = tcpLsn.AcceptSocket() 'Se queda esperando la conexion de un cliente
IDClienteActual = .Socket.RemoteEndPoint
.Thread = New Thread(AddressOf LeerSocket)
SyncLock Me
      Clientes.Add(IDClienteActual, InfoClienteActual) ' Esta es la hashTable donde los almaceno.
End SyncLock
RaiseEvent NuevaConexion(IDClienteActual)
.Thread.Start()


Y luego para renovar la info del cliente:

Dim InfoClienteActual As InfoCliente
Dim IDReal as Net.IpEndPoint
'Aqui obtengo la ID del cliente
' Y renuevo la posicion de la tabla con los datos nuevos
InfoClienteActual.Nombre = "Pepito"
Clientes(IDReal) = InfoClienteActual


Pero en algún punto es donde se pierde y borra toda la información que no es del socket ni del thread, incluso si creo un nuevo formulario manager para el cliente, pierde la referia hasta el y devuelve Nothing en todos los campos, menos los dos que dije antes.

Novlucker

No tengo el otro pc conmigo (el que tiene el visual)  :-\ , pero a simple vista tu problema estaría cuando renuevas?
Creas una nueva estructura ... cambias nombre ... buscas la anterior en el hashtable y pisas el item con el último que habías creado?
Quizás hay algo que no estoy entendiendo  :xD



Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Kasi

En teoria si, pero no deberia afectar a la hora de perder datos, lo que hago es :

Busco el cliente que le corresponde, actualizo sus datos, pero en ningun momento borro los que ya tiene existentes, y por último actualizo el cliente machacando lo que habia en ese hueco de la HashTable y metiendo la estructura actualizada.La primera vez recupera correctamente los datos, pero la segunda y sucesivas no, puede ser que no esté sobreescribiendo el mismo index de la Hashtable y haya 2 pero recupere el incorrecto?

Novlucker

No, no creo que sea problema del hashtable, porque solo puede haber un dato con un nombre, no puede estar repetido

Seguro que estas tomando la misma estructura? para mi estas creando una nueva y estas machacando la que tenías antes en el hashtable, pero como digo, quizás no me estoy dando cuenta de como tienes armado el código completo

Te recomiendo agregar algunos puntos de interrupción y ver donde se pierden los datos, es lo más sencillo  :-\
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

raul338

Una pregunta. Guardas los datos en alguna clase???. Ejemplo, Tienes una clase que se llame "Cliente" y que tenga las propiedades Threads y Sockets???.....

Si es asi tal vez sea tu problema eso, estas usando punteros (si!!! en vb.net existen, se crean automaticamente :E  ;D)

Yo tuve cierto problema cuando usaba pilas y las usaba pasando como parametros a travez de metodos. En un metodo tenia que pasarlo como valor para poder hacer lo que quiera con la copia (la vaciaba y su contenido lo mostraba en un listbox) pero cuando queria usar la original, estaba vacia!!!!  :o :o :o (las 2 clases apuntan a la misma sección de memoria, o sea, un puntero  ::))

Si es asi, tengo un codigo para ayudarte, si es "a medias" asi, puedes implementar una clase y yo te doy un codigo para que puedas "clonarla" y que no se pisen los datos. Y si no es asi, pense cualquier fruta   :xD :laugh: ;D

Kasi

Bueno bueno...ya tengo localizado donde llega el problema, pero sigo dandole vueltas...os dejo el code para que veais...

En esta función es en la que espero las conexiones de clientes, que una vez conectados les asigno un hilo para cada uno para que la siguiente funcion , LeerSocket() se encargue de ir leyendo cada cliente.Lo de lecturas de clientes no tiene problema, no confunde Ids ni nada, es decir lee correctamente del socket que le corresponde, pero por lo que parece cuando el socket deja de recibir el comando con la info de los datos del cliente para recibir cualquier otro comando, es cuando pierdo los datos...

Private Sub EsperarCliente()
        On Error Resume Next
        Dim InfoClienteActual As InfoDeUnCliente
        InfoClienteActual = Nothing
        With InfoClienteActual
            While True
                .Socket = tcpLsn.AcceptSocket() 'Se queda esperando la conexion de un cliente
                IDClienteActual = .Socket.RemoteEndPoint
                .Thread = New Thread(AddressOf LeerSocket)
                .Ip = IDClienteActual.Address.ToString
                SyncLock Me
                    Clientes.Add(IDClienteActual, InfoClienteActual)
                End SyncLock
                RaiseEvent NuevaConexion(IDClienteActual)
                .Thread.Start()
            End While
        End With
    End Sub


Con esta función proceso el lo que llega por el socket del cliente...

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(1024) {}
                    Try
                        Ret = .Socket.Receive(Recibir, Recibir.Length, SocketFlags.None)
                        If Ret > 0 Then
                            .UltimosDatosRecibidos = Encoding.ASCII.GetString(Recibir)
                            SyncLock Me
                                Clientes(IDReal) = InfoClienteActual ' Aqui actualizo los datos nuevos que llegan del cliente...
                            End SyncLock                                   'pero solo deberia afectar al campo de Ultimos datos recibidos y no al resto..                       
                            TotalDatos(Ret, lbDatosReci)
                            RaiseEvent DatosRecibidos(IDReal)
                        Else
                            RaiseEvent ConexionTerminada(IDReal)
                            Exit While
                        End If
                    Catch e As Exception
                        If Not .Socket.Connected Then
                            RaiseEvent ConexionTerminada(IDReal)
                            Exit While
                        End If
                    End Try
                End If
            End While
            Call CerrarThread(IDReal)
        End With
    End Sub


El ajo se está cociendo en la Función de LeerSocket, estoy convencido, pero soy incapaz de ver lo que está pasando, creo que de tanto mirarlo ya no lo veo y seguro que es un error tonto...

raul338

Cita de: Kasi en  1 Agosto 2009, 16:16 PM
SyncLock Me
    Clientes(IDReal) = InfoClienteActual ' Aqui actualizo los datos nuevos que llegan del cliente...
End SyncLock                                   'pero solo deberia afectar al campo de Ultimos datos recibidos y no al resto..     

Eso lo estas haciendo demas, como te dije, estas sobrescribiendo un puntero, intenta quitar esa linea, cualquier cambio que hagas en el array, es guardado automaticamente (si no lo quieres asi, solo dime y yo te paso el code  ;D)

en lo demas, creo deberia estar bien

Kasi

Vale he quidado los SynckLock, y parece que ahora la estructura no se pierde, pero no actualiza los datos que le llegan, es decir es como si siempre se quedara con los datos almacenados del primer comando y no renueva lo que tiene en UltimosDatosRecibidos con la nueva información que se envia.

Supongamos, que desde un cliente envian una "a", cuando no hay datos si que mete en UltimosDatosRecibidos la "a", pero si posteriormente ese cliente envia como datos "b", sigue mostrando "a", y no renueva UltimosDatosRecibidos = "b".

Y cuando consigo que los UltimosDatosRecibidos sean = "b", es cuando pierdo el resto de datos de ese cliente que tengo en la estructura  :-(