只要我一直在试图用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的最简单的方法? :■

有帮助吗?

解决方案

一个典型的线路阅读器是这样的:

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

(注意,我们已经移动到功能这一点,并去掉了“做什么”,用“产量返回”时,它创建一个迭代器(一个懒惰地迭代的,非缓冲状态机)替换它

我们将随后消耗这个简单,如:

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

现在我们的加工代码并不需要担心的如何的读线 - 简单的的线的序列,做一些与他们

请注意的是,usingDispose())适用于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());
    }
}

其他提示

在服务器代码的同时是设置为只读每个连接一行。你需要在尝试中的另一个同时读取所有的线被发送。我认为,一旦流是在客户端安装程序,它会发送所有的数据。然后,在服务器端,您的信息流是仅有效地从该特定流中读取一行。

尝试这样做,得到了

类型或命名空间名称“流”找不到(是否缺少using指令或程序集引用?) 类型或命名空间名称“的StreamReader”找不到(是否缺少using指令或程序集引用?) 类型或命名空间名称“的StreamReader”找不到(是否缺少using指令或程序集引用?) “System.Net.Sockets.Socket”不包含一个定义为“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是插座。 对于一些改划TcpClient类不正确的个人电脑上任何更多的工作, 但Socket类作品就好。

UTF-8是绞合的StreamReader /写入器编码

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top