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

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top