WiFi Server Download

I have a csv file on an SD card of all my application data logs. I was wanting to stream/download this file using the wifi module for the FEZ spider. I saw this topic (http://www.tinyclr.com/forum/topic?id=8114) and was wondering if there was a way to download it instead of creating a webpage.

Thanks for your help :slight_smile:

Weston, you are asking a very general question.

I tried to look at your forum profile, to see if I could establish a context for a response, but you have not provided any information.

You could write a simple TCP server on the Spider, and have the remote machine connect to download the data. Is this the
type of response you are looking for?

you could setup the spider to act as a server and then stream a xml rsponse to a socket or web request or any other multitude of eternet based requests. XML format makes the data from your app consumable by jut about anything you can think of

steps could be

1 - A client app that connects to the spider
2 - spider recieves requests
3 - spider fetches current stored data
4 - spider collates data into a nice to read xml stream
5 - client receives xml stream and decode it
6 - client could then store data in a database or process it a nice winrt app maybe :slight_smile:

just wondering why you are storing the data in csv format? not that there is anything wrong with that. I just seem to think that storing data in a xml format seems to me to be a nice approach these days especially when retrieving the stoed infomation converting to a xdoc and then utilising the power of LINQ queries. the data becomes a searchable collection much like a database query.

Sorry about the generalism of the question …lol
I have a thread that writes to a sd card.


 //If SD Card is mounted and inserted
                if (_sdcard.IsCardMounted)
                {
                    lock (_locker)
                    {
                        //If Items are in the queue
                        while ((log_queue.Count > 0) && (action.Count > 0))
                        {
                            message = log_queue.Dequeue().ToString();
                            thrd_action = (Thread_Action)action.Dequeue();
                           
                            //Get Root Directory
                            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;

                            switch (thrd_action)
                            {
                                case Thread_Action.Log_Action:
                                    using (StreamWriter sw = new StreamWriter(rootDirectory + @ "\Application_log.csv", true))
                                    {
                                        sw.WriteLine(RealTimeClock.GetTime().ToString() + ", Log_Action, " + message);
                                        sw.Close();
                                        Debug.Print(RealTimeClock.GetTime().ToString() + ", Log_Action, " + message);
                                    }
                                    break;

                                case Thread_Action.Record_Data:
                                    using (StreamWriter sw = new StreamWriter(rootDirectory + @ "\data_log.csv", true))
                                    {
                                        sw.WriteLine(RealTimeClock.GetTime().ToString() + ", Data_Action, " + message);
                                        sw.Close();
                                        Debug.Print(RealTimeClock.GetTime().ToString() + ", Data_Action, " + message);
                                    }
                                    break;

                                case Thread_Action.Save_Settings:
                                    _config.Save();
                                    break;
                            }
                        }
                    }
                }

I have one for applications logs and the other for recording a fish tank temperature periodically. I was thinking it would be cool to download these files via wifi instead of pulling the SD Card out (which requires unscrewing stuff). That way I can analyze the files at a later time using excel. These logs will get bigger over time. I was wanting to create a way to download the file like an internet browser downloads a file via website link/address. The url I saw converted the data into a html page which is nice but when these files get bigger that to me might not be a great way to view the data. I have a websever already created which shows the current statuses of the software.


WebServer.StartLocalServer(_wifi.NetworkSettings.IPAddress, 80);
                index = WebServer.SetupWebEvent("index", WebServer_RefreshRate);
                
                index.WebEventReceived += new WebEvent.ReceivedWebEventHandler(index_WebEventReceived);


void index_WebEventReceived(string path, WebServer.HttpMethod method, Responder responder)
        {
            string response = "<html>\n<head>\n";
            string tableBreak = "<tr><td><center>----------------------</center></td><td><center>----------------------</center></td></tr>\n";

            response += "<center><h1>Aquarium Control System Status/Settings Page</h1></center>\n";
            response += Resources.GetString(Resources.StringResources.css) + "\n\n";
            response += "</head><body>\n";
            response += "<center>\n";
            response += "<table id=\"table-6\">\n";
            response += "<thead>\n";
            response += "<th>Property</th>\n";
            response += "<th>Value</th>\n";
            response += "</thead>\n";

            response += "<tbody>\n";
            response += "<tr><td>Current Clock Value:</td><td>" + RealTimeClock.GetTime().ToString("MM dd yyyy - hh:mm:ss:tt") + "</td></tr>\n";
            response += "<tr><td>Current Temp:</td><td>" + appSettings.CurrentTemp.ToString() + "</td></tr>\n";
            response += "<tr><td>Current Temp Units:</td><td>" + functions.Convert_TempFormat_To_String(appSettings.Display_Temp) + "</td></tr>\n";
            response += "<tr><td>Responder Path:</td><td>" + responder.Path + "</td></tr>\n";
            response += "<tr><td>HTTPVersion:</td><td>" + responder.HTTPVersion + "</td></tr>\n";
            response += "<tr><td>Client Endpoint:</td><td>" + responder.ClientEndpoint + "</td></tr>\n";
            response += "<tr><td>IsDhcpEnabled:</td><td>" + _wifi.NetworkSettings.IsDhcpEnabled + "</td></tr>\n";
            response += "<tr><td>PhysicalAddress:</td><td>" + functions.Convert_Bytes_to_String(_wifi.NetworkSettings.PhysicalAddress) + "</td></tr>\n";
            response += "<tr><td>NetworkInterfaceType:</td><td>" + _wifi.NetworkSettings.NetworkInterfaceType.ToString() + "</td></tr>\n";
            response += "<tr><td>SubnetMask:</td><td>" + _wifi.NetworkSettings.SubnetMask + "</td></tr>\n";
            response += tableBreak;
            response += "<tr><td>Bubbles Off Time:</td><td>" + functions.Extract_Time_From_Datetime(appSettings.BubblesOffTime) + "</td></tr>\n";
            response += "<tr><td>Bubbles On Time:</td><td>" + functions.Extract_Time_From_Datetime(appSettings.BubblesOnTime) + "</td></tr>\n";
            response += "<tr><td>Heater Off Temp:</td><td>" + appSettings.HeaterOffTemp + "</td></tr>\n";
            response += "<tr><td>Heater On Temp:</td><td>" + appSettings.HeaterOnTemp + "</td></tr>\n";
            response += "<tr><td>Light Off Time:</td><td>" + functions.Extract_Time_From_Datetime(appSettings.LightOffTime) + "</td></tr>\n";
            response += "<tr><td>Light On Time:</td><td>" + functions.Extract_Time_From_Datetime(appSettings.LightOnTime) + "</td></tr>\n";

            response += tableBreak;
            response += "<tr><td>Wifi Status:</td><td>" + StatusString + "</td></tr>\n";

            if (Status == WiFiStatus.Connected)
            {
                response += "<tr><td>SSID:</td><td>" + CurrentInfo.SSID + "</td></tr>\n";
                response += "<tr><td>IPAddress:</td><td>" + _wifi.NetworkSettings.IPAddress.ToString() + "</td></tr>\n";
                response += "<tr><td>RSSI:</td><td>" + "-" + CurrentInfo.RSSI + " dB</td></tr>\n";
                response += "<tr><td>Physical Address:</td><td>" + functions.Convert_Bytes_to_String(CurrentInfo.PhysicalAddress) + "</td></tr>\n";
                response += "<tr><td>Network Type:</td><td>" + _wifiNetworkType[(int)CurrentInfo.networkType] + "</td></tr>\n";
                response += "<tr><td>Security Mode:</td><td>" + _securityMode[(int)CurrentInfo.SecMode] + "</td></tr>\n";
                response += "<tr><td>Channel Number:</td><td>" + CurrentInfo.ChannelNumber + "</td></tr>\n";
            }

            response += tableBreak;
            response += "<tr><td>Heater On:</td><td>" + appSettings.HeaterRelay.ToString() + "</td></tr>\n";
            response += "<tr><td>Bubbles On:</td><td>" + appSettings.BubblesRelay.ToString() + "</td></tr>\n";
            response += "<tr><td>Light On:</td><td>" + appSettings.LightRelay.ToString() + "</td></tr>\n";
            response += "</tbody></table></center></body></html>\n";
            
            byte[] bytes = new System.Text.UTF8Encoding().GetBytes(response);
            responder.Respond(bytes, "text/html");
        }

If there are any other questions, please let me know or you see a better way to do something too :slight_smile:

@ Weston Bridgewater - You are right where you want to be then. All you will have to do is construct a header with the size and type of the file, and the file information itself. (Refer to RFC-2616 Section 14 (HTTP/1.1: Header Field Definitions) for proper construction of headers). The browser will then determine what to do with the file after that (display, run, save, etc).

@ James - Thanks for the info!

Also note (on a performance/memory optimization topic) that each one of those + signs creates a whole new string, which only lasts until the next + sign, and then must be garbage collected. String concatenation is to be avoided, especially on these tiny memory-limited devices.

1 Like