문제

간단히 나는 무엇을 구현하려고 노력했다 BufferedStreamReader Java로합니다. 소켓 스트림이 열려 있고 라인별로 라인을 라인 지향적 인 방식으로 읽고 싶습니다.

다음 서버 코드가 있습니다.

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());
            }
        }

그리고 다음 클라이언트 코드 :

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();
        }

서버는 첫 번째 줄만 읽습니다 (login>user,pass) 그리고 ReadLine NULL을 반환합니다!

Java 's에서와 같이이 라인 지향 독자를 달성하는 가장 쉬운 방법은 무엇입니까? BufferedStreamReader? :에스

도움이 되었습니까?

해결책

일반적인 라인 리더는 다음과 같습니다.

using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
    string line;
    while((line = reader.ReadLine()) != null) {
        // do something with line
    }
}

(참고 using 우리를 보장하기 위해 Dispose() 오류가 발생하고 루프가 발생하더라도)

원한다면 반복자 블록으로 이것 (관심 분리)을 추상화 할 수 있습니다.

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;
        }
    }
}

(우리는 이것을 함수로 옮기고 "do do something"을 제거하여 "수율 리턴"으로 대체하여 반복자 (게으르게 반복되지 않은 상태의 상태 기계)를 만듭니다.

그런 다음 이것을 간단하게 소비합니다.

foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
    // do something with line
}

이제 우리의 처리 코드는 걱정할 필요가 없습니다 어떻게 줄을 읽으려면 - 간단히 주어진 일련의 선 순서, 그들과 함께 무언가를하십시오.

주목하십시오 using (Dispose())에 적용됩니다 TcpClient 도; 당신은 확인하는 습관을 가져야합니다 IDisposable; 예를 들어 (여전히 오류 로깅 포함) :

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());
    }
}

다른 팁

서버 코드에서는 연결 당 하나의 줄만 읽을 수 있도록 설정됩니다. 전송되는 모든 줄을 읽으려고 시도하는 동안 다른 사람이 필요합니다. 일단 스트림이 클라이언트 측에서 설정되면 모든 데이터를 보내겠다고 생각합니다. 그런 다음 서버 측에서 스트림은 특정 스트림에서 한 줄만 효과적으로 읽습니다.

이것을 시도하고 얻었습니다

유형 또는 네임 스페이스 이름 '스트림'을 찾을 수 없습니다 (지침 또는 어셈블리 참조를 사용하여 누락 되었습니까?) 유형 또는 네임 스페이스 이름 ''Streamreader '를 찾을 수 없습니다 (사용 지시서 또는 어셈블리 참조를 사용하지 않습니까?). 유형 또는 네임 스페이스 이름 'Streamreader'를 찾을 수 없습니다 (디렉토리 또는 어셈블리 참조를 사용하여 누락 되었습니까?)

    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는 소켓입니다. 일부 곡을 위해 TCPClient 클래스는 더 이상 내 PC에서 작동하지 않지만 소켓 클래스는 잘 작동합니다.

UTF-8은 스트리트 스트리어 리더 / 라이터 인코딩입니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top