C # - não StreamReader.ReadLine não funcionar correctamente!
-
11-09-2019 - |
Pergunta
Simplesmente eu tenho tentado para implementar o que BufferedStreamReader
faz em Java. Eu tenho um fluxo de soquete aberto e só quero lê-lo de uma forma orientada-line - linha por linha
Eu tenho o seguinte código do servidor.
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());
}
}
E o código de cliente seguinte:
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();
}
O servidor lê apenas a primeira linha (login>user,pass
) e depois ReadLine
retorna nulo!
O que é a maneira mais fácil de alcançar este leitor orientada a linha como no BufferedStreamReader
de Java? : S
Solução
Uma linha-leitor típico é algo como:
using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
string line;
while((line = reader.ReadLine()) != null) {
// do something with line
}
}
(note a using
para garantir que Dispose()
-lo mesmo se teremos um erro, eo loop)
Se você quiser, você pode abstract este (separação de preocupações) com um bloco de iterator:
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;
}
}
}
(nota mudamos isso em uma função e removeu a "fazer algo", substituindo-a por "retorno de rendimento", o que cria um iterador (a preguiçosamente iterado, buffer não-máquina de estado)
Em seguida, iria consumir isso como simplesmente como:
foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
// do something with line
}
Agora o nosso código de processamento não precisa se preocupar com a como para ler linhas -. Simplesmente dada uma sequência de linhas, fazer algo com eles
Note que o using
(Dispose()
) aplica-se a TcpClient
também; você deve fazer um hábito de verificar para IDisposable
; por exemplo (ainda incluindo o seu erro-logging):
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());
}
}
Outras dicas
A, enquanto em seu código de servidor está configurado para somente leitura uma linha por conexão. Você vai precisar de outro, enquanto dentro da tentativa de ler todas as linhas que está sendo enviada. Eu acho que uma vez que o fluxo está configurado no lado do cliente, ele vai enviar todos os dados. Em seguida, no lado do servidor, seu fluxo, efetivamente, apenas lendo uma linha a partir desse fluxo particular.
tentei isso e tenho
O tipo ou nome do namespace 'stream' não pôde ser encontrado (faltam usando uma diretiva ou uma referência assembly?) O tipo ou nome do namespace 'StreamReader' não pôde ser encontrado (faltam usando uma diretiva ou uma referência assembly?) O tipo ou nome do namespace 'StreamReader' não pôde ser encontrado (faltam usando uma diretiva ou uma referência assembly?) 'System.Net.Sockets.Socket' não contém uma definição 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 é um soquete. para alguns rezone a classe TcpClient não funciona bem no meu pc mais, mas a classe Socket funciona muito bem.
UTF-8 é a encalhado StreamReader / Encoding Escritor