07
Apr
12

Streamsocket example c# metro

Peter Daukintis

This is a very basic example of socket communication in a c# metro-style application using StreamSocket and StreamSocketListener. It mirrors the Simple StreamSocket example in msdn here http://code.msdn.microsoft.com/windowsapps/StreamSocket-Sample-8c573931 which is coded in c++ and javascript but no c#. I decided to roughly convert it as a learning exercise – please note I haven’t tested the code in that many scenarios and haven’t handled failure cases and errors much.

A socket provides send and receive over TCP and a StreamSocketListener will listen for incoming TCP connections.

The sample will act as a server or client depending on which buttons you press, i.e. press listen to be a server and connect to be a client. Also, you can set the same program as client and server ad have it communicate with itself.

To start the listener wire up a connection received event handler and bind the service name…

_listener.ConnectionReceived += listenerConnectionReceived;
await _listener.BindServiceNameAsync("3011");

The event handler stores the incoming socket in a list (so it can use it to reply), and waits for incoming data from it. The ‘waiting for incoming data’ bit looks like this…

async private void WaitForData(StreamSocket socket)
{
    var dr = new DataReader(socket.InputStream);
    //dr.InputStreamOptions = InputStreamOptions.Partial;
    var stringHeader = await dr.LoadAsync(4);

    if (stringHeader == 0)
    {
        // disconnected
        return;
    }

    int strLength = dr.ReadInt32();
    uint numStrBytes = await dr.LoadAsync((uint)strLength);
    string msg = dr.ReadString(numStrBytes);
    WaitForData(socket);
}

It uses a DataReader to read from the incoming socket and then calls itself to wait for subsequent incoming message data.

Note that the samples use a protocol which sends the length (number of bytes) of the message first followed by the message data itself. If you want to use a different strategy, for example characters to delimit the start and end of a message then the code will change a little bit. The difference being that you won’t always know how much data to read. You can modify the code like this to accommodate this:

async private void WaitForData(StreamSocket socket)
        {
            var dr = new DataReader(socket.InputStream);
            dr.InputStreamOptions = InputStreamOptions.Partial;
            var stringHeader = await dr.LoadAsync(512);

            // change the rest acccordingly….

Note that setting the InputStreamOptions to Partial will allow you to specify a larger buffer but also the async load operation will complete when a smaller sized buffer comes in. This enables you to read the data coming in and respond to it accordingly.

The pictures show a session between a socket server running on a build slate and a win8 vm both on my local network..

socketexampleservertablet

socketexampleclientvm

The project can be downloaded from here.

https://skydrive.live.com/redir.aspx?cid=4f1b7368284539e5&resid=4F1B7368284539E5!445&parid=4F1B7368284539E5!123

UPDATE: This project has been updated for the Release Preview

http://sdrv.ms/Nema94

About these ads

12 Responses to “Streamsocket example c# metro”


  1. 1 jokeefe
    July 20, 2012 at 7:16 pm

    Thank you! I was having trouble reading input from a StreamSocket until I saw how you were using InputStreamOptions.Partial. My problem was that I was trying to read a smaller input with too large of a buffer, so it was hanging indefinitely.

  2. 2 John Baird
    August 24, 2012 at 11:12 pm

    I’ve been having trouble with a project i’m working on. It throws a datareader/datawriter error saying “the object is closed.”. I downloaded your project and ran it and am receiving the same error. Do you know anything about this? Any suggestions?

    To duplicate it, try listening, connecting, send 1 message, reply 1 message, send another message…

    Thanks…

  3. October 14, 2012 at 6:14 am

    Hi Peter,
    This may be misunderstanding StreamSockets, but this is all well and good – and I have your sample running, however the chat client and server are within the one application? Wouldn’t I need to host the ‘server’ component on a server somewhere on a windows service or something?

    I try to implement the server code on any other project type, WPF, console app etc. and I can’t find Windows.Networking namespace.

    Now I’m really confused, I wouldn’t want the server to be another Windows Store app?
    Hope you can shed some light on this!

    • October 14, 2012 at 6:14 pm

      Hi graham,

      Yes, I could well have separated the code into distinct server and client parts. I just wanted to show both parts of the code from a winrt perspective and having each endpoint act as both seemed simpler to me. In general if you want to code either client or server in a different technology then you would need to use the stack which is available in that environment. In this case though you can use WinRT apis from .NET desktop applications. I have an example in my latest post which shows a WPF socket server working with a a metro client see http://babaandthepigman.wordpress.com/2012/10/12/metro-app-and-kinect-voice-control/

  4. October 15, 2012 at 5:18 am

    Ah, awesome. That makes sense, thanks. I’ve also since been looking at trying to use it with the Microsoft.WebSockets NuGet package too. Will take a look at your WPF client, thanks.

  5. February 13, 2013 at 2:22 am

    Is it necessary to send/recv the size of the message? I’m trying to get the listener to work with a telnet client and its giving a bit of trouble.

    • February 17, 2013 at 6:00 pm

      It’s not necessary to send the size of the message – this is just a way of ‘framing’ the data (you need some way to determine the beginning/end of a message)

      • February 17, 2013 at 6:36 pm

        I’m trying to make a simple test server using StreamSocketListener that I can telnet to. For some reason the telnet client cannot connect to it. Netstat shows there is a tcp connection listening on the port I chose. Any idea? Have you by chance used the listener and connected a telnet client to it? I’ve done this before using .net tcplistener w/o issue.

  6. 9 George Hailazopoulos
    April 23, 2013 at 4:06 pm

    I separated the code into client/server but i could not get it to work.
    When i was trying to connect from client to my already running server i was getting an error(due to time out i suspect my server was unreachable) .I tried localhost and ip and different ports but i had no luck any ideas on what i may be missing?

    ++I think your facebook link does not work although i connected through i was unable to post a comment++


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: