C # - StreamReader.ReadLine no funciona correctamente!
-
11-09-2019 - |
Pregunta
Simplemente he estado tratando de poner en práctica lo hace BufferedStreamReader
en Java. Tengo un flujo de socket abierto y sólo quiero leerlo de una manera orientada a la línea - línea por línea
Tengo el siguiente servidor de código.
while (continueProcess)
{
try
{
StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8);
string command = reader.ReadLine();
if (command == null)
break;
OnClientExecute(command);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Y el cliente siguiente código:
TcpClient tcpClient = new TcpClient();
try
{
tcpClient.Connect("localhost", serverPort);
StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
writer.AutoFlush = true;
writer.WriteLine("login>user,pass");
writer.WriteLine("print>param1,param2,param3");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
tcpClient.Close();
}
El servidor sólo lee la primera línea (login>user,pass
) y luego ReadLine
devuelve un valor nulo!
¿Cuál es la forma más fácil de lograr este lector orientado a líneas como lo es en BufferedStreamReader
de Java? : S
Solución
Una línea-lector típico es algo como:
using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
string line;
while((line = reader.ReadLine()) != null) {
// do something with line
}
}
(nótese el using
para asegurar que Dispose()
que incluso si conseguimos un error, y el bucle)
Si lo desea, podría Resumen Este (separación de intereses) con un bloque de iterador:
static IEnumerable<string> ReadLines(Stream source, Encoding encoding) {
using(StreamReader reader = new StreamReader(source, encoding)) {
string line;
while((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
(en cuenta que hemos pasado esto en una función y eliminado el "hacer algo", sustituyéndolo por "retorno de rendimiento", lo que crea un iterador (un perezosamente iterado, la máquina de estado no-buffering)
Nos entonces consumir esta tan simple como:
foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
// do something with line
}
Ahora nuestro código de procesamiento no necesita preocuparse por ¿Cómo para leer líneas -. Simplemente dada una secuencia de líneas, hacer algo con ellos
Tenga en cuenta que la using
(Dispose()
) se aplica a TcpClient
también; usted debe hacer un hábito de comprobación de IDisposable
; por ejemplo (aún incluyendo su registro de errores):
using(TcpClient tcpClient = new TcpClient()) {
try {
tcpClient.Connect("localhost", serverPort);
StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
writer.AutoFlush = true;
writer.WriteLine("login>user,pass");
writer.WriteLine("print>param1,param2,param3");
} catch (Exception ex) {
Console.Error.WriteLine(ex.ToString());
}
}
Otros consejos
El tiempo en el código del servidor se configure sólo para leer una línea por cada conexión. Usted necesitará otra, mientras que en el intento de leer todas las líneas que se envía. Creo que una vez que la corriente está configurado en el lado del cliente, que va a enviar todos los datos. A continuación, en el lado del servidor, su flujo es de hecho solo leer una línea de esa corriente en particular.
intentado esto y tiene
El tipo o espacio de nombres 'corriente' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) El tipo o espacio de nombres 'StreamReader' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) El tipo o espacio de nombres 'StreamReader' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado?) 'System.Net.Sockets.Socket' no contiene una definición para 'GetStream'
public string READS()
{
byte[] buf = new byte[CLI.Available];//set buffer
CLI.Receive(buf);//read bytes from stream
string line = UTF8Encoding.UTF8.GetString(buf);//get string from bytes
return line;//return string from bytes
}
public void WRITES(string text)
{
byte[] buf = UTF8Encoding.UTF8.GetBytes(text);//get bytes of text
CLI.Send(buf);//send bytes
}
CLI es un socket. por alguna Rezone la clase TcpClient no funciona bien en mi pc más, pero la clase Socket funciona muy bien.
UTF-8 es la StreamReader / Codificación escritor hebra