locked
LoadAsync and StreamSocket RRS feed

  • Question

  • I'm using the StreamSocket to open a TCP connection where I send commands and I get responses. My problem is that I don't know beforehand the length of the response, if a response will be sent and the protocol has nothing indicating this. LoadAsync requires me to know this, or it will wait forever. Is there anything in the StreamSocket that will tell me if there's data pending to be transmitted? My current "solution" is to LoadAsync(1) and loop until I get a \n, which is generally a good indication that the message is over... but if I don't get a response at all (which is completely valid in the protocol) or if the response has many lines, I run the risk of waiting forever. Maybe I should be using another kind of socket, but StreamSocket seemed to be the most appropriate. Thanks! J 
    Sunday, September 25, 2011 12:57 AM

Answers

All replies

  • If the streamSocket sample doesn't say how to do this, it will soon :-)

     

    There's an "InputStreamOptions" on the DataReader; one of the options is a "partial" option.  This will let you specify a large buffer, but as soon as there's any data, you get the callback.  

    Link: http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.inputstreamoptions

     

    • Marked as answer by Joaquin Jares Wednesday, September 28, 2011 1:41 PM
    Sunday, September 25, 2011 4:09 PM
  • hi Jares, is your StreamSocket code written in C++?
    • Edited by Mr_Jones_ Wednesday, September 28, 2011 6:41 AM
    Wednesday, September 28, 2011 6:41 AM
  • Nope, C#. I didn't yet have time to try the options, but I will today.
    Wednesday, September 28, 2011 10:46 AM
  • Partial in the options does exactly what I needed. The documentation is not very clear, though :(. Thanks!
    Wednesday, September 28, 2011 1:41 PM
  • Jares, if don't mind sharing C++ sample code, thanks in advance!


    • Edited by Mr_Jones_ Thursday, October 6, 2011 2:21 AM
    Friday, September 30, 2011 2:30 AM
  • My code is c#, and it looks like this:
     
            private async Task<string> ReadStringAsync(DataReader reader)
            {
                var lastChar = string.Empty;
                var fullString = string.Empty;
                while (lastChar.EndsWith("\n")) 
                {
                    var count = await reader.LoadAsync(512); //512 is the buffer length
                    lastChar = reader.ReadString(count); //and count is the actual number of returned bytes
                    fullString += lastChar;
                }
                return fullString;
            }
    This will not work in many situations (such as when you get two lines in the same message), but you can see how loadasync is used there. The data reader is created here:
                var socket = new StreamSocket();
                await socket.ConnectAsync(new HostName("example.com"), portNumber, SocketProtectionLevel.PlainSocket);
                
                var reader = new DataReader(socket.InputStream);
                reader.InputStreamOptions = InputStreamOptions.Partial;
    Hope this helps!
    Friday, September 30, 2011 5:18 AM
  • If the streamSocket sample doesn't say how to do this, it will soon :-)

     

    There's an "InputStreamOptions" on the DataReader; one of the options is a "partial" option.  This will let you specify a large buffer, but as soon as there's any data, you get the callback.  

    Link: http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.inputstreamoptions

     


    I have the same problem. it's helpful ,Thanks
    Wednesday, November 9, 2011 3:50 AM
  • My code is c#, and it looks like this:
            private async Task<string> ReadStringAsync(DataReader reader)
            {
                var lastChar = string.Empty;
                var fullString = string.Empty;
                while (lastChar.EndsWith("\n")) 
                {
                    var count = await reader.LoadAsync(512); //512 is the buffer length
                    lastChar = reader.ReadString(count); //and count is the actual number of returned bytes
                    fullString += lastChar;
                }
                return fullString;
            }
    This will not work in many situations (such as when you get two lines in the same message), but you can see how loadasync is used there. The data reader is created here:
                var socket = new StreamSocket();
                await socket.ConnectAsync(new HostName("example.com"), portNumber, SocketProtectionLevel.PlainSocket);
                
                var reader = new DataReader(socket.InputStream);
                reader.InputStreamOptions = InputStreamOptions.Partial;
    Hope this helps!

    Mhh interesting, but I can't create the client.. I have tried this:

    StreamSocket client = new StreamSocket();
    HostName host = new HostName(myIP);
    client.ConnectAsync(host, myPort, SocketProtectionLevel.PlainSocket);
    DataWriter data = new DataWriter(client.OutputStream);
    String hello = "Hello World";
    Int32 len = (Int32)data.MeasureString(hello);
    data.WriteInt32(len);
    data.WriteString(hello);

    I guess I have to use the data.WriteAsyc() method.. but I don't understand how I should use it.

    We really need a sample in C#... because C++ and JS are too complex too understand.

    Saturday, April 7, 2012 1:17 PM
  • On any asynchronous operation (they usually are denoted by ending in "Async" for example ConnectAsync) you need to use the await keyword from an async method.

    You must await client.ConnectAsync( .. ) which will throw an exception you can catch upon connection failure.

    In addition, to write to a DataWriter you need to await the StoreAsync method on it.

    • Proposed as answer by NelsonCarrillo Saturday, April 7, 2012 4:03 PM
    Saturday, April 7, 2012 4:03 PM