C# - StreamReader.Readline이 제대로 작동하지 않습니다!
-
11-09-2019 - |
문제
간단히 나는 무엇을 구현하려고 노력했다 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은 스트리트 스트리어 리더 / 라이터 인코딩입니다