|
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mensajes - aTx
Páginas: [1]
1
« en: Miércoles 25 de Febrero de 2009, 00:23 »
Hola a todos. He implementado una clase Socket que funciona mediante comandos numéricos y eventos, es decir, cada envío que se realiza se identifica mediante un comando numérico, que el receptor se encarga de recibir e invocar un evento indicando el número de comando y los datos que este lleva. Por ahora es funcional, pero me gustaría contar con la revisión de alguien que tuviese cierta experiencia en Sockets de .Net y que me pueda aconsejar alguna mejora o cambio. Además, falla cuando los datos enviados son grandes (sobre los 100kbytes) y se envían otros datos a la vez, porque, según creo, mezcla el contenido de ambos paquetes y el resultado es erróneo (El fallo se suele producir en la línea 195, pues recibe un valor de TamañoSecuencia erróneo). Aquí os dejo el código: using System; using System.IO; using System.Net.Sockets; namespace Sockets { /// <summary> /// Delegado empleado para los eventos de recepción de comandos /// </summary> delegate void DelegadoComandoRecibido(CanalComunicacion canal, UInt16 comando, BinaryReader datos); /// <summary> /// Administra una canal (Socket) de comunicación entre los dos extremos de la conexión /// </summary> class CanalComunicacion { /// <summary> /// Constructor /// </summary> public CanalComunicacion(Socket socket) { Socket = socket; //Establecer opciones de socket socket .LingerState = new LingerOption (true, 5); //Establecer recepción asíncrona comenzarRecepcion(); } /// <summary> /// Destructor /// </summary> ~CanalComunicacion() { Cerrar(); } #region Campos /// <summary> /// Socket usado para el envío y recepción de datos /// </summary> public readonly Socket Socket; public bool Conectado { get { return Socket.Connected; } } #endregion /// <summary> /// Evento invocado cuando se recibe un comando por este canal /// </summary> public event DelegadoComandoRecibido ComandoRecibido; /// <summary> /// Evento invocado cuando se cierra el canal o un error corta la comunicación /// </summary> public event EventHandler CanalCerrado; /// <summary> /// Cierra la comunicación entre los dos extremos /// </summary> public void Cerrar() { if (Socket.Connected) { Socket.Shutdown(SocketShutdown.Both); Socket.Close(); } if (CanalCerrado != null) CanalCerrado(this, EventArgs.Empty); } /// <summary> /// Envía un comando al otro extremo de la conexión por el canal especificado /// </summary> public void EnviarComando(UInt16 comando, params object[] datos) { MemoryStream buffer = new MemoryStream (2 + datos .Length*50); BinaryWriter escritor = new BinaryWriter (buffer ); UInt32 tamañoSecuencia = 0; //Este valor es el primer elemento que se envía, pero se calcula al finalizar de generar el buffer escritor.Write(tamañoSecuencia); escritor.Write(comando); foreach (object parametro in datos) { { escritor.Write(parametro.ToString()); } { byte[] bytes = (byte[]) parametro; escritor.Write((UInt32) bytes.Length); escritor.Write(bytes); } else if (parametro is UInt16 ) { escritor.Write((UInt16) parametro); } else if (parametro is UInt32 ) { escritor.Write((UInt32) parametro); } else if (parametro is UInt64 ) { escritor.Write((UInt64) parametro); } else if (parametro is int) { escritor.Write((int) parametro); } } //Calcular el tamaño de la secuencia y escribirlo en el buffer tamañoSecuencia = (UInt32) buffer.Length - 4; //No contar el tamaño propio del numero (4 bytes) buffer.Position = 0; escritor.Write(tamañoSecuencia); Socket .BeginSend(buffer .GetBuffer(), 0, (int) buffer .Length, 0, new AsyncCallback (finEnvio ), buffer ); } /// <summary> /// Finaliza un envío asíncrono y libera los recursos /// </summary> private void finEnvio(IAsyncResult ar) { if (Socket.Connected == false) { Cerrar(); } else { Socket.EndSend(ar); MemoryStream buffer = ar.AsyncState as MemoryStream; if (buffer != null) buffer.Close(); } } /// <summary> /// Comienza la recepción asíncrona de los datos enviados por el otro extremo /// </summary> private void comenzarRecepcion() { if (Socket.Connected == false) { Cerrar(); } else { Buffer buffer = new Buffer { BytesBuffer = new byte[4], TamañoSecuencia = -1 }; Socket .BeginReceive(buffer .BytesBuffer, 0, buffer .BytesBuffer.Length, 0, new AsyncCallback (finRecepcion ), buffer); } } class Buffer { public Int32 TamañoSecuencia; public byte[] BytesBuffer; } /// <summary> /// Termina de recibir los datos enviados por el otro extremo de la conexión, /// y los procesa /// </summary> private void finRecepcion(IAsyncResult ar) { if (Socket.Connected == false) { Cerrar(); return; } int recibidos = Socket.EndReceive(ar); if (recibidos > 0) { Buffer buffer = (Buffer)ar.AsyncState; if (buffer.TamañoSecuencia < 0)//Recibido tamaño de la próxima secuencia { buffer.TamañoSecuencia = BitConverter.ToInt32(buffer.BytesBuffer, 0); //Recibir el resto de la secuencia buffer .BytesBuffer = new byte[buffer .TamañoSecuencia ]; Socket.BeginReceive(buffer.BytesBuffer, 0, buffer.TamañoSecuencia, 0, new AsyncCallback (finRecepcion ), buffer ); } else//Datos recibidos { //Comenzar a recibir siguiente comando comenzarRecepcion(); //Invocar eventos MemoryStream bufferStream = new MemoryStream (buffer .BytesBuffer); BinaryReader lector = new BinaryReader (bufferStream ); UInt16 comando = lector.ReadUInt16(); if (ComandoRecibido != null) ComandoRecibido(this, comando, lector); lector.Close(); } } else { Cerrar(); } } } }
Un Saludo.
2
« en: Martes 21 de Octubre de 2008, 18:08 »
Hola, estoy de nuevo por aquí xD
He intentado implementar el algoritmo que me dijiste, aunque no lo he conseguido completamente creo al menos las ideas principales si están implementadas. Por ahora estoy es lo que consigo para plotear el valor 0,6:
[attachment=1:1dcczbkc]plot.png[/attachment:1dcczbkc]
En la imagen se ve para cada punto, su orden de dibujo. Si uniese ordenadamente las líneas, como en un juego de niños, no saldría la figura correcta, como me pasaba en casos anteriores. ¿Tienes alguna idea para solucionar esto?
Te adjunto un archivo de log que creo que puede serte muy útil para comprender lo que intento explicar. Un Saludo.
[attachment=0:1dcczbkc]log.txt[/attachment:1dcczbkc]
3
« en: Viernes 17 de Octubre de 2008, 17:32 »
Intentare implementar lo que dices, aunque ahora mismo estoy un poco perdido... Ya te iré contando como voy.
Por cierto, he hallado otros recursos para lo que busco por internet: codeproject .com /KB/cs/ScoOterVisualizationPart2.aspx mysite. verizon .net /~vze2vrva/thesis.html
4
« en: Miércoles 15 de Octubre de 2008, 20:59 »
No es exactamente una imagen, sino una red de circuitos eléctricos acoplados, pero el tratamiento debe de ser similar: son celdas con valores (en este caso, los valores son voltajes), que no se pueden mover ni ordenar porque variaría el orden de la red y por tanto no serviría.
Cuando me refiero a figuras más complejas es a las "líneas de nivel" que hacen formas mas extrañas, como las de la imagen, en las que claramente mi algoritmo no sirve y obtengo formas extrañas.
[attachment=1:31xue8li]image.png[/attachment:31xue8li]
Cuando el resultado debería ser aproximadamente esto (obtenido con Matlab):
[attachment=0:31xue8li]untitled.jpg[/attachment:31xue8li]
Explícame un poco mas el concepto de líneas de nivel, pues creo que se aplica lo que intento realizar.
Un saludo
5
« en: Miércoles 15 de Octubre de 2008, 12:17 »
Un ejemplo de como lo hago para contonear el valor 0.1:
[attachment=0:1cz4y6qt]anim.png[/attachment:1cz4y6qt]
Empiezo por la celda 0101 y la comparo con su derecha, la 0201. Como el valor no está entre esas dos celdas, entonces comparo entre 0101 y su superior, 0102. Como no he encontrado el valor entre ninguna de las celdas, repito los mismos pasos con la celda 0102, es decir, comparo los valores de 0102 con 0202 y luego con 0103. En este caso, al comparar 0102 con 0103,la primera tiene el valor 0.09806 y la segunda 0.1139, por tanto, el 0.1 está entre esas dos celdas. Simplemente calculo el punto donde debería estar y lo dibujo entre dichas celdas, y repito esos pasos para todas las celdas y valores que quiero buscar.
6
« en: Miércoles 15 de Octubre de 2008, 10:40 »
Interpolar consiste en "adivinar" donde está un valor dados otros valores que ya tienes. Por ejemplo, si tienes un 5 y un 8, si quieres interpolar un 6 sabrás, por lógica, que está más cerca del 5 que del 8, exactamente a 1/3 de la distancia de 5 y 2/3 de distancia de 8.
En la wikipedia inglesa tienes varios ejemplos mas: wikipedia.org/wiki/Interpolation
7
« en: Martes 14 de Octubre de 2008, 20:01 »
Estoy realizando una aplicación que requiere interpolación de valores en un array bidimensional. Simplemente, consiste en varias celdas que toman distintos valores, y mi aplicación tiene que buscar unos valores específicos e interpolarlos de la información que se posee. Aquí va un ejemplo:
[attachment=1:1wle29n2]interpolacion.png[/attachment:1wle29n2]
Mi actual implementación consiste en recorrer todas las celdas y comparar, una a una, con su celda derecha y su superior (empezando desde la parte inferior izquierda), y si el valor está entre esas dos celdas, interpolar el punto donde debería estar el valor buscado y dibujar dicho punto. Pero esto no es efectivo, ya que para figuras mas complejas no es capaz de seguir el orden natural de las figuras, creando formas extrañas e inútiles, como las de esta imagen:
[attachment=0:1wle29n2]interpolacion_mala.png[/attachment:1wle29n2]
¿Se os ocurre alguna otra forma, o conocéis algún algoritmo que me permita realizar lo que pretendo?
Un Saludo.
8
« en: Martes 23 de Septiembre de 2008, 23:28 »
Pues eso, me gustaría saber si puedo configurar el IntelliSense de VS2008 para que se muestre automaticamente cada vez que escribo el comienzo del nombre de una variable o función, al estilo de C#, y sin tener que estar pulsando Ctrl+Espacio.
Saludos!!
Páginas: [1]
|
|
|