Autor
|
Tema: Estructura Perruna - ¿Donde falla? (Leído 6,511 veces)
|
Kasi
Desconectado
Mensajes: 76
|
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.
|
|
|
En línea
|
|
|
|
Novlucker
Ninja y
Colaborador
Desconectado
Mensajes: 10.683
Yo que tu lo pienso dos veces
|
Lenguaje? Así como así no se me ocurre ... sería bueno que dejes el code o fragmento de code donde ocurre esto Saludos
|
|
|
En línea
|
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
Desconectado
Mensajes: 76
|
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.
|
|
|
En línea
|
|
|
|
Novlucker
Ninja y
Colaborador
Desconectado
Mensajes: 10.683
Yo que tu lo pienso dos veces
|
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
|
|
|
En línea
|
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
Desconectado
Mensajes: 76
|
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?
|
|
|
En línea
|
|
|
|
Novlucker
Ninja y
Colaborador
Desconectado
Mensajes: 10.683
Yo que tu lo pienso dos veces
|
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
|
|
|
En línea
|
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
Desconectado
Mensajes: 2.633
La sonrisa es la mejor forma de afrontar las cosas
|
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 ) 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!!!! (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
|
|
|
En línea
|
|
|
|
Kasi
Desconectado
Mensajes: 76
|
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...
|
|
|
En línea
|
|
|
|
raul338
Desconectado
Mensajes: 2.633
La sonrisa es la mejor forma de afrontar las cosas
|
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 ) en lo demas, creo deberia estar bien
|
|
|
En línea
|
|
|
|
Kasi
Desconectado
Mensajes: 76
|
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
|
|
|
En línea
|
|
|
|
|
|