我一直在尝试实现Java中BufferedStreamReader
的功能。我打开了一个套接字流,只想逐行地逐行阅读它。
我有以下服务器代码。
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 BufferedStreamReader
中一样? :■
答案 0 :(得分:13)
典型的线路阅读器类似于:
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 something”,将其替换为“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());
}
}
答案 1 :(得分:5)
服务器代码中的while设置为每个连接只读取一行。在尝试读取所有发送的行时,您将需要另一个。我想一旦在客户端设置了该流,它将发送所有数据。然后在服务器端,您的流实际上只从该特定流中读取一行。
答案 2 :(得分:0)
试过这个并得到了
找不到类型或命名空间名称'Stream'(您是否缺少using指令或程序集引用?) 找不到类型或命名空间名称'StreamReader'(您是否缺少using指令或程序集引用?) 找不到类型或命名空间名称'StreamReader'(您是否缺少using指令或程序集引用?) 'System.Net.Sockets.Socket'不包含'GetStream'的定义
答案 3 :(得分:0)
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类不再适用于我的电脑, 但是Socket类工作正常。
UTF-8是搁浅的StreamReader / Writer编码