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!

Responder a