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…
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…
{
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:
{
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..
The project can be downloaded from here.
UPDATE: This project has been updated for the Release Preview
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.
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…
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!
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/
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.
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.
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)
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.
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++
A simple socket programming example in c#…..C# Socket programming
watson
Does this example still exist somewhere?
I’m looking for an example of a StreamSocket that is receiving on the client side.
Yes, are the links not working for you?
Link wasn’t working when I posted but it appears to be back now. Weird.