Main Site Documentation

TCP socket example


#1

Can anyone point me in the direction of a comprehensive example of using TCP sockets to allow several .netmf wired or wireless clients (I’ll be using either Spider or Cobra) to send data to and from a c# app running on PC?

There is a good example here but both client and server are full Dot Net.

http://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

Many thanks.


#2

@ andre.m - It seems like this is initiating the request and then reading the response. I was really looking for something that didn’t need to initiate a request before receiving a response. I just want to be able to send instructions from the PC to the NETMF board and have it do stuff…


#3

Yeah, the NETMF is the client as there might be several.


#4

Why not send a request from PC-side?. On the NETMF/Gadgeteer side you look for the Content of the request and according to the different content you do different stuff with the device.
Edit: You can send commands to different NETM/Gageteer Servers which have different IP-Address.


#5

Sounds like either way could work. I’m just more used to thinking about a single server and multiple clients I guess. However, having the NETMF as a server might have it’s benefits too.


#6

@ Jason -
If you should decide to have the client on the PC-Side perhaps my little HttpClientApp of this project
https://www.ghielectronics.com/community/codeshare/entry/927
can be useful. Only GET requests are implemented but it should be easy to extend it to PUT requests.


#7

@ andre.m, @ Jason - the direct ip socket solution is the one I always look at first, its easy, works pretty much on all network devices, do your own xml syntax, can do your own little message encryption/decription if the case needs it and by making the netmf device the server you could reach it from not only a PC, but from another networked netmf device (or even more) as well … having a bluetooth listener as well one can limit on the reach or use it as a fall back (PAN/LAN) … but like you said, it all pretty much depends on what the goal is …

Just as a possibility, you could try to implement UPnP (or WSDP) on the .netmf device and spend the device an admin site (with protection and security if need be) so you don’t care who the client is, you can reach it from any browser in the network … (programmatic reachable services can be offered in UPnP too, if not a must be to UPnP protocol standards, if I remember correctly) …

Edit: WSDP should be DPWS


#8

PiWi, how might that code look? Should I wrap the socket connection in a using block and then send the buffer there? If the socket then goes out of scope how do I receive bytes?

For example:


using (socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
    socket.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.65"), 80));
    var sendBuffer = Encoding.UTF8.GetBytes("Hello World!");
    socket.Send(sendBuffer,0,sendBuffer.Length, SocketFlags.None);
}

The above code is in its own thread, but once out scope how does the sever send data to the client; the socket connection is closed?


#9

@ Jason - Have a happy new year and have a read on the following:

TCP - C/S: http://mikedodaro.net/2011/12/05/a-tcp-server-using-net-gadgeteer/
UDP - C/S: http://mikedodaro.net/2012/07/23/creating-an-udp-server-with-net-gadgeteer/


#10

@ PiWi - I’ll take a look at these and keep you posted. Probably going to get a Mountaineer board too so I have something with Ethernet built-it. I will probably base a new board of my own on this design too.


#11

@ PiWi - The examples make for interesting reading. It seems as though they don’t hold the socket connection open forever, but uses the REST service to receive and store the data and then get the Gadgeteer to poll the server every 15 seconds to check for changes.

That’s an interesting approach and one that might work well with my Azure Web API code. I’ll have to dig further into that.

I’m still working on having a socket connection between a Gadgeteer and a PC. It seems that many examples close the socket once the transfer is made. I think however, that I need to keep mine open if I am to send and receive at any time; or should I have both the PC and Gadgeteer be a client and a server? How might that work with more that one Gadgeteer?

More research me thinks…


#12

@ Jason - one could think of a xml variant and specify the source into some xml setting so you know where it comes from asnd communicate always the same structure from any gadgeteer. Or take and misfill some http headers or take some of your own defined http headers. Depends a bit this being a commecrcail product or lives with your intranet only …

I did several projects on a normal server where I put the same into a windows background service. Using a mukti-threaded async ip socket listener and depending on the content react according. Using this listener I do process control, commucating via web services (soap) running reports, one is free to implement whatever and the darn thing is running since 2006 for the first version and had no fail yet this was even x-platform. Currently I’m doing the third version of it generating soap ws calls making 100+ calls on a row (last time I looked 600+) and that with an average response of less than a second from initiation -> system1 -> server2 -> ws calls -> internet -> respose ws -> server2 -> system1 and then again for mutiple hundred of times … but … all in full .net … and yes noth sides do have a client and server side of the socket communication

Currently trying to get it on netmf, and I have to think of an alternative to generics … have to manage and destroy the MT socket request … and keep the xml load thin even with the limited support of xml document objects etc. that makes life a little bit complicated …


#13

@ PiWi @ Json

This sounds very interesting guys. I would suggest you don’t use XML but JSON. There are now several JSON libraries for NETMF out there. And the good thing is (same as XML) it can be read, parsed and used on both sides NETMF and .NET (regular).

I see the incompatibility of serialization from netmf to .NET as a major issue.

One advantage over XML (I see) is less overhead. No “<” and “>”, no XML headers and no XML parsing.

The only thing I am currently wrapping my head around is something like signaling, without having to poll things all the time from the device. Something like an Incoming-Network-Traffic-Event. Maybe via interrupts? Not sure.


#14

@ AWSOMEDEVSIGNER - Use message queing


#15

@ PiWi - Something like that?

http://www.codeproject.com/Articles/167917/Microsoft-Message-Queuing-A-Simple-Multithreaded-C


#16

@ AWSOMEDEVSIGNER - Something like that, but I’m not aware of any msmq clients in the netmf ego-system

since this is based on ip sockets and since I already do have a working solution for sockets
I do first think of a solution in that direction …

But you being an Azure guy, isn’t this possible via ASB, hub and notifcation services ?


#17

@ PiWi - Yes, sure :slight_smile: But I am looking for a more generalized approach, more like a base-library to implement other libraries, without worrying about the threading and eventing parts. Something like a general network listener that does not use the while(true) approach but something like hardware based signaling.

Because I think that inter-device and device to external services makes the scenario complete.

EDIT: Maybe I should look into the network drivers written for some Gadgeteer modules and do a reality check.


#18

@ AWSOMEDEVSIGNER - What about reactive extensions (MSDN) ?

Look here: http://joseoncode.com/2011/06/17/event-driven-http-server-in-c-with-rx-and-httplistener/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using AsyncHttp.Server;

namespace AsyncHttp
{
    class Program
    {
        static void Main()
        {
            var subject = new Subject<string>();

            using(var server = new HttpServer("http://*:5555/"))
            {
                var listeners = server
                        .Where(ctx => ctx.Request.HttpMethod == "GET")
                        .Subscribe(ctx => subject.Take(1)
                                                 .Subscribe(m => ctx.Respond(new StringResponse(m))));

                var publisher = server
                    .Where(ctx => ctx.Request.HttpMethod == "POST")
                    .Subscribe(ctx => ctx.Request.InputStream.ReadBytes(ctx.Request.ContentLength)
                                          .Subscribe(bts =>
                                                         {
                                                             subject.OnNext(Encoding.UTF8.GetString(bts));
                                                             ctx.Respond(new EmptyResponse(201));
                                                         }));


                Console.ReadLine();

                listeners.Dispose();
                publisher.Dispose();

            }
        }
    }
}

But that won’t fly in netmf … maybe gives you ideas …


#19

@ PiWi - Awesome! Thanks! :clap:

EDIT: Recently I saw a port for NTMF, but totally forgot about that: https://rx.codeplex.com/SourceControl/network/forks/dcazzulino/rxmicro


#20

@ AWSOMEDEVSIGNER - Maybe a closer look at the WebServer implementation should be given. The webserver is having its received action(s) event based maybe that approach can be used as well …


        void RunWebServer()
        {
            WebServer.StopLocalServer();
            Thread.Sleep(1000);
            WebServer.StartLocalServer(wifiRS21.NetworkInterface.IPAddress, 80);
            WebServer.DefaultEvent.WebEventReceived += DefaultEvent_WebEventReceived;

            // Keep on living
            while (true) Thread.Sleep(1000);
        }

        void DefaultEvent_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            Debug.Print(DateTime.Now + " DefaultWebEvent received...");
            //
            switch (method)
            {
                case WebServer.HttpMethod.DELETE:
                    responder.Respond("Hello world, default handler for DELETE method");
                    break;
                case WebServer.HttpMethod.GET:
                    Debug.Print(DateTime.Now + " URL: " + responder.Path);
                    Debug.Print(DateTime.Now + " Remote request from: " + responder.ClientEndpoint);
                    Debug.Print(DateTime.Now + " Headers: " + new String(System.Text.Encoding.UTF8.GetChars(responder.HeaderData)));
                    responder.Respond(ConvertStringByteArrayUsingEncodingUTF8(TimeRespons()), "text/html"); //"Hello world, default handler for GET method");
                    break;
                case WebServer.HttpMethod.POST:
                    responder.Respond("Hello world, default handler for POST method");
                    break;
                case WebServer.HttpMethod.PUT:
                    responder.Respond("Hello world, default handler for PUT method");
                    break;
                default:
                    responder.Respond("Hello world, default handler for UNKNOWN method");
                    break;
            }
            Debug.Print(DateTime.Now + " DefaultEvent done.");
        }