Sending a multiline string over NamedPipe?

岁酱吖の 提交于 2019-12-12 02:23:24

问题


How can I send a multiline string with blank lines over a NamedPipe?

If I send a string

string text= @"line 1 
line2

line four
";
StreamWriter sw = new StreamWriter(client);
sw.Write(text);

I get on the server side only "line 1":

StreamReader sr = new StreamReader(server);
string message = sr.ReadLine();

When I try something like this

StringBuilder message = new StringBuilder();
string line;
while ((line = sr.ReadLine()) != null)
{
    message.Append(line + Environment.NewLine);
}

It hangs in the loop while the client is connected and only releases when the client disconnects.

Any ideas how I can get the whole string without hanging in this loop? I need to to process the string and return it on the same way to the client.

It's important that I keep the original formatting of the string including blank lines and whitespace.


回答1:


StreamReader is a line-oriented reader. It will read the first line (terminated by a newline). If you want the rest of the text, you have to issue multiple readlines. That is:

StreamReader sr = new StreamReader(server);
string message = sr.ReadLine(); // will get "line1"
string message2 = sr.ReadLine(); // will get "line2"

You don't want to "read to end" on a network stream, because that's going to hang the reader until the server closes the connection. That might be a very long time and could overflow a buffer.

Typically, you'll see this:

NetworkStream stream = CreateNetworkStream(); // however you're creating the stream
using (StreamReader reader = new StreamReader(stream))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        // process line received from stream
    }
}

That gives you each line as it's received, and will terminate when the server closes the stream.

If you want the reader to process the entire multi-line string as a single entity, you can't reliably do it with StreamReader. You'll probably want to use a BinaryWriter on the server and a BinaryReader on the client.




回答2:


Why not just call ReadToEnd() on StreamReader?

StreamReader sr = new StreamReader(server);
string message = sr.ReadToEnd();



回答3:


I accomplished sending multiple line messages over a named pipe by using token substitution to replace all \r and \n in the message with tokens like {cr} and {lf} thus converting multiple lines messages into 1 line.

Of course, I needed to do the reverse conversion of the receiver side.

The assumption is that the substituted tokens will never be found in the source text.

You can make sure that this happens by also substituting all "{" with {lp}. That way the "{" becomes your escape character.

You can use Regex to make these Replacements.

That worked great and allowed me to use StreamReader.



来源:https://stackoverflow.com/questions/4412686/sending-a-multiline-string-over-namedpipe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!