Типичный читатель строки - что-то вроде:
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;
}
}
}
(обратите внимание, что мы переместили это в функцию и удалили «сделать что-то», заменив его «yield return», который создает итератор (ленино итерированный, не буферизованный конечный автомат)
Тогда мы бы потребляли это так же просто, как:
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());
}
}