Hola, Tene en cuenta que puede ser que no recibas un numero entero de mensajes por receive, en otras palabras, puede ser que un mensaje te llegue mitad en un receive y mitad en el siguiente.
Es posible que esto no lo hayas notado en las pruebas que hiciste pero puede pasar en situaciones en que el server te envie muchos mensajes juntos (sobre todo en caso de que el conjunto de mensajes ocupe mas de 1500 bytes). Con respecto al procesamiento de la respuesta en otro thread, entiendo que lo que sugeria el colega es que recibas en un thread y almacenes en buffer y que proceses ese buffer en otro thread distinto. Asi es como se hace esto usualmente. Recomiendo que mires los articulos que sugeri en mi post anterior. ---------------------------------- Carlos Peix 2010/8/3 Marcel Felix <[email protected]> > Hola Gracias a todos por sus observaciones. > > El problema lo tenía con el buffer. Efectivamente estaba haciendo la > suposición errónea de que cada receive me devolvía un mensaje. Como sí tengo > un protocolo que señala tanto el inicio como el fin de paquete nada más tuve > que ver cuantos paquetes recibo cada vez que hago el receive. > > Aunque en la muestra de código que mandé no se ve muy claro, si hago el > procesamiento de la respuesta en otro thread. > > Ayer mismo hice los ajustes y por la noche pude probarlo. Ya no tuve > mensajes incompletos y tampoco perdí uno solo. > > > > Gracias de nuevo a todos!! > > El 2 de agosto de 2010 11:20, <[email protected]> escribió: > >> En particular, en base al ejemplo que enviás, además te sugeriría que >> prestes atención a lo siguiente. >> >> a) no veo que el buffer se inicialice justo antes de la llamada a >> recibirmensaje() >> qué pasa si el buffer de 100 elementos no se inicializó, recibió en el >> mensaje anterior 100 elementos y en este 90? vas a tener un buffer en el que >> vas a tener 90 elementos del mensaje actual y los 10 últimos del mensaje >> anterior. sì, ya sè, procesás sólo datosRecibidos... mmmm.... >> >> b) no te recomendaría procesar los mensajes dentro del mìsmo método que >> los recibe. partiendo de un criterio de diseño (algo que se conoce como >> single responsability) te diría que tengas un método para recibr y una vez >> que recibas dispares un método para procesar. pensalo del siguiente modo, >> mañana podrías necesitar procesar mensajes que vinieran por distintos >> canales. no sería buena idea tener que recordar que en cada método que >> recibe un mensaje, tenés que llamar a procesar al mensaje. >> >> c) es condición que te envíen siempre 100 caracteres ? o 100 es un máximo >> ? no hay acordado un caracter que identifique el final de un mensaje o algo >> así? >> >> d) hay, además, algún protocolo mediante el cual se maneje la >> comunicación? se envían algún tipo de confrimación de recepción del mensaje, >> del tipo "ack" ? sin el cual el mensaje se reenvía o algo así? >> >> d) cuál es el contexto en que evaluás que no recibís una respuesta? cómo >> sabés que efectivamente del otro lado se escuchó la pregunta? >> >> >> *----- Original Message -----* >> *From:* Carlos Peix [mailto:[email protected]] >> *To:* [email protected] >> *Sent:* Mon, 2 Aug 2010 15:02:54 -0300 >> *Subject:* [puntonet] Pregunta Socket >> >> Hola, >> >> Tu aplicacion puede recibir y enviar cientos de mensajes por segundo, no >> te preocupes por eso ya que no es una limitacion de sockets. Tambien >> deberias saber que no es trivial implementar una buena solucion custom de >> sockets. >> >> En cuanto a tu primer duda: el socket envia y recibe bytes, no existe, a >> este nivel, concepto de mensaje. Usualmente y dependiendo del tamaño de la >> "ventana" y una cuestion de optimizacion del uso de la red, puede acumular >> varios bytes en datagramas y tambien puede cortar en cualquier lugar. >> >> Definitivamente es un error asumir que una llamada a receive te va a >> devolver un mensaje, lo que te devuelve son los bytes disponibles en ese >> momento. >> >> Para evitar la perdida de partes de mensajes deberias almacenar los bytes >> entrantes en un buffer y analizarlo para ir extrayendo mensajes completos. >> Para determinar que es un mensaje completo deberias establecer un protocolo >> de nivel superior, por ejemplo una marca de inicio de mensaje y una de fin. >> >> >> En cuanto a tu segunda duda, probablemente se deba a que tu implementacion >> de lectura y escritura del socket no es asincronica. Te remito a estos >> articulos que me han servido de mucho. >> >> // Asynchronous Client Socket Example >> // http://msdn2.microsoft.com/en-us/library/bew39x2a(VS.71).aspx >> >> // Using an Asynchronous Client Socket >> // http://msdn2.microsoft.com/en-us/library/bbx2eya8(VS.71).aspx >> >> >> // Asynchronous Server Socket Example >> // http://msdn2.microsoft.com/en-us/library/fx6588te(VS.71).aspx >> >> // Using an Asynchronous Server Socket >> // http://msdn2.microsoft.com/en-us/library/5w7b7x5f(VS.71).aspx >> >> // http://www.csharphelp.com/archives3/archive486.html >> >> Suerte >> >> ---------------------------------- >> Carlos Peix >> >> 2010/8/2 Marcel Felix <[email protected]> >> >> Hola a todos, buen día. >> >> Tengo una aplicación desarrollada con c# framework 2.0. Esta aplicación >> consiste en un socket que recibe envia y recibe mensajes, cadenas de texto >> de alrededor de 100 caracteres. El intercambio de mensajes es intensivo la >> mayor parte del día. Alrededor de 90 - 100 por minuto y en horas pico hay >> lapsos de hasta 160 - 170 por minuto. >> Mi aplicación se encarga de enviar los mensajes conforme van llegando, uno >> tras otro, y la recepción de mensajes la tengo implementada en un thread que >> llama a una función que recibe mensajes y es de la siguiente forma: >> >> void recibirmensaje() >> { >> while(conectado) //variable booleana que se asigna a true cuando >> hago la conexion del socket >> { >> if(socket.available > 0) >> { >> datosrecibidos = socket.receive(buffer); >> respuestaServidor = Encoding.ASCII.GetString(buffer, 0, >> datosRecibidos); >> //la cadena recibida la proceso en otro thread >> cMensajeRecibido oMjs = new >> cMensajeRecibido(respuestaServidor, CadenaCn, tiempoEspera, appPath, >> SegundosTimeOut); >> new Thread(new ThreadStart(oMjs.ProcesarRespuesta)).Start(); >> >> } >> } >> } >> >> Pero tengo dos problemas: >> El primero es que a veces la respuesta no la recibo completa. En lugar >> de los 100 caracteres recibo la mitad. Lo primero que se me ocurre es que >> del otro lado no me esten mandando la cadena completa pero ¿es posible >> que sea mi función la que no está haciendo bien la lectura? ¿por que >> solo ocurre cuando hay muchos envios y respuestas seguidos? >> Si del otro lado siempre me mandan las respuestas completas ¿Hay >> alguna manera de asegurar que mi aplicación reciba todas las respuestas >> completas? >> >> El segundo es que a veces hago el envío y la respuesta no la recibo, o >> no la alcanzo a recibir. Esto ocurre cuando hago muchas peticiones >> seguidas, por ejemplo en el mismo segundo. En este caso mis dudas son >> similares al primer punto, y asumiendo de entrada que del otro lado sí me >> estan respondiendo todas. >> >> Es decir ¿Hay alguna manera de optimizar el uso del socket para que reciba >> la mayor cantidad de respuestas que le lleguen? >> >> ¡Gracias! >> >> >> >
