views:

79

answers:

1

Hi all,

From the internet I got the way to read a huge string from a NetworkStream.

 static NetworkStream ns = null;
 static StringBuilder sb = null;
 static byte[] buffer = null;
 static int position = 0;
 //.......................................
 //other codes skipped for simplicity
 //....................................... 
 private static string Read()
 {
        if (ns.CanRead)
        {
            sb.Clear();
            position = 0;
            while (ns.DataAvailable)
            {
                position = ns.Read(buffer, 0, buffer.Length);
                sb.Append(Encoding.Unicode.GetString(buffer, 0, position));
            }

            return sb.ToString().Trim();
        }
        else
        {
            return null;
        }
 }

However, I cannot find an example how to write a huge string to a NetworkStream.

Is there a "symmetrical" pattern for writing as we do for reading?

Thank you in advance.

+4  A: 

That reading code is dangerously wrong in many ways:

  • By using static variables in this way, it's hopelessly unsuitable for multi-threaded tasks. (I hope that's just due to you simplifying it...)
  • It never initializes the variables to non-null values - again, hopefully that's not the real code
  • It uses the DataAvailable property to decide when it should be "done" - that's incredibly dangerous as it means if a packet is delayed in the stream, you could read half as much data as you expected to
  • It uses Encoding.Unicode always, which is rarely the best choice of encoding
  • It assumes that it will always read a whole number of characters. What if one character is split between reads? That's what the Encoder/Decoder classes are for... but you don't really need to use them here anyway - see below.

I would strongly suggest that you wrap the NetworkStream in a StreamReader for reading, and a StreamWriter for writing. That's what they're for. You can then read a line at a time, or just a char[] buffer, or to the end of the stream (which means "until the socket is closed"). This is fine for a text-only protocol.

If you've got a protocol which mixes text and binary data, life becomes a lot harder. Personally I like protocols which length-prefix messages - that way you can read only the data you're meant to, and then perform whatever conversion you want.

Anyway, I hope this random selection of thoughts helps... if you want more detailed assistance, please provide details of what protocol you're using.

Jon Skeet
+1 for the DataAvailable notice
onof
Thank Jon Skeet for your useful comments. Frankly, I am a newbie in programming world.*) I used static fields because this fields are in a static class to instantiate exactly a single object. The object will behave as a server agent listening for multiple clients.*) In the static ctor, I will assign all null fields.*) You are right. For short string data, I can read the whole data. However for the long one, I obtain incomplete packet. It confused me.*) So what is the best encoding, ASCII ? I work only for ASCII characters actually.OK, I will rewrite my codes.Thanks very much.
xport
I would suggest using UTF-8, to be honest - for ASCII data it will be exactly the same, but it means you can cope with all of Unicode in the future. I would still *highly* recommend that you get rid of the static data. Try to think in a more object-oriented way.
Jon Skeet
When I wrap NetworkStream in StreamReader, calling ReadToEnd() will block the application. Is it wrong to call ReadToEnd()?Anyway, how to attach my code to my comment here?
xport
@xport: Edit your question instead of putting code in comments. However, you're right: `ReadToEnd` will indeed block until the other end closes the connection. If you don't want that, don't call `ReadToEnd` :) *Any* of the read methods will block, of course. It's hard to suggest what you should do without knowing more about what you're trying to achieve.
Jon Skeet
Thank Jon Skeet. I will write my scenario very detailed now. Tomorrow I will let you know. Roughly speaking, my scenario is to develop an ASP.NET application that allows clients to enter mathematics expressions, processes the expressions, and finally sends them back to the clients.For example: A client submits x^2+sin(x) to my page Integrator.aspx. The page code behind forwards the input to MAXIMA kernel. Maxima is a computer algebra system that works as a client in socket mechanism. The processed data will be sent back to the page code behind, which in turn, submits it to the client.
xport
What I am doing now is to develop an assembly to establish communication between ASP.NET code behind and MAXIMA kernel.
xport
@xport: Please give a link to the network protocol maxima uses. That's the only really important thing here.
Jon Skeet
@Jon Skeet, Thank you for your reply.I already asked a member of MAXIMA mailing list about the protocol or format that Maxima uses. He is Robert Dodier (contact e-mail: robert (period or dot) dodier (at or @) gmail (dot or period) com). According to him, Maxima works as a client. To instantiate it, just call maxima.bat with a switch -s followed by portnumber. Other switches are also available such as --very-quiet to suppress the startup message and expression labels. Use --help switch if you want list the other switches.Up to now, I haven't found the protocol manual.
xport
@Jon Skeet, Maxima works as a client agent and uses TCP/IP protocol to connect to server agent. If the server agent sends a command such as integrate(x^3,x) then the client send the result, i.e., 1/4*x^4. The issues is that the output format sent by client (maxima) to server (user) sometimes contains additional flags. For example, if server sends tex(integrate(x,x)), the outpub becomes $$\frac{x^2}{x}$$ followed by a flag of FALSE. The output is a simple string (not binary).
xport
@xport: You need more information than "uses TCP/IP protocol" - you need to know the application layer protocol. What signifies the end of a command? What encoding does it use? Can you send multiple commands on the same connection, or is it like HTTP-1.0?
Jon Skeet
OK Jon, I will search for this information.
xport
I already create a forum for this project. I hope there are many more people interested to help me. :) http://sourceforge.net/projects/aspmaxima/forums/forum/1190702/topic/3786806/index/page/1
xport