¿Puedo leer la transmisión de TcpClient de una mejor manera?

Tengo un sistema donde en un extremo tengo un dispositivo comunicándose con un módulo vía RS-232. El módulo se conecta a una PC a través de TCP y traduce los mensajes TCP a RS-232 y viceversa.

Así es como lo hago:

  1. Leo cada byte en el flujo
  2. construir una cuerda
  3. compare la última parte de la cadena con un delimitador
  4. luego dejo de leer la secuencia (y disparo un evento, aunque no se muestra aquí).

Mi código actual para manejar esto es

        string delimiter = "\r\n";
        byte[] reply = new byte[1];
        string replyString = string.Empty;
        bool readOk = true;
        int dl = delimiter.Length;
        bool delimiterReached = false;

        do
        {
            try
            {
                stream.Read(reply, 0, 1);
            }
            catch (Exception e)
            {
                readOk = false;
                break;
            }

            replyString += Encoding.ASCII.GetString(reply, 0, reply.Length);

            int rl = replyString.Length;

            if (rl > dl)
            {
                string endString = replyString.Substring(rl-dl, dl);
                if (endString.Equals(delimiter))
                    delimiterReached = true;
            }

        } while (!delimiterReached);

sin que importe stream es la TcpClient.GetStream()

No me importa mucho la construcción constante de cadenas, así que me preguntaba si hay una mejor manera de hacer esto.

preguntado el 12 de junio de 12 a las 16:06

Tienes razón en que no te guste la construcción constante de cuerdas. Este código creará una nueva cadena cada vez que llegue un byte. Echa un vistazo a StringBuilder en lugar de. -

¿No perdería aún algo de rendimiento en el string endString = stringBuilder.ToString(rl-dl, dl);? -

Simplemente haga la verificación directamente en el objeto stringbuilder: "delimiterReached = (StringBuilder.ToString().Substring(start, length) == delimiter);" <-- establece el booleano en verdadero o falso. -

1 Respuestas

Una vez establecida la conexión TCP, envuelva el TcpClient corriente en un StreamReader:

var reader = new StreamReader( stream, Encoding.ASCII );

Dado que su delimitador es \r\n, StreamReader.ReadLine leerá un mensaje completo:

var reply = reader.ReadLine();

Tenga cuidado de crear el StreamReader una vez por conexión TCP; puede leer y almacenar en búfer datos adicionales del flujo TCP subyacente para mayor eficiencia.

Respondido el 12 de junio de 12 a las 18:06

Puedo ver en la implementación que se basa principalmente en búferes char[] y pequeñas cadenas (construcción), así que supongo que es más rápido. Sin embargo, mi delimitador no siempre es \r\n, a veces es "FIN DEL ARCHIVO", o alguna otra locura. - Kasperhj

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.