using System; using System.Net; using System.Net.Sockets; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.NetduinoPlus; using System.Text; namespace NetduinoPlusApplication1 { public class Program { public static OutputPort led; public static WebServer webServer; public static void Main() { led = new OutputPort(Pins.ONBOARD_LED, false); webServer = new WebServer(); webServer.ListenForRequest(); } public class WebServer : IDisposable { private Socket socket = null; public WebServer() { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(new IPEndPoint(IPAddress.Any, 80)); socket.Listen(10); ListenForRequest(); } public void ListenForRequest() { while (true) { using (Socket clientSocket = socket.Accept()) { int bytesReceived = clientSocket.Available; if (bytesReceived > 0) { byte[] buffer = new byte[bytesReceived]; clientSocket.Receive(buffer, bytesReceived, SocketFlags.None); string request = new string(Encoding.UTF8.GetChars(buffer)); int start = request.IndexOf("cmd="); string OMG = ""; if (start > 0) { start += 4; int stop = request.IndexOf(" ", start); OMG = request.Substring(start, stop - start); } switch(OMG) { case"START": led.Write(true); break; case "STOP": led.Write(false); break; default: break; } string header = "HTTP/1.0 200 OK\r\nContent-Type: text; charset=utf-8\r\nContent-Length: " + OMG.Length.ToString() + "\r\nConnection: close\r\n\r\n"; clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None); clientSocket.Send(Encoding.UTF8.GetBytes(OMG), OMG.Length, SocketFlags.None); } } } } #region IDisposable Members ~WebServer() { Dispose(); } public void Dispose() { if (socket != null) socket.Close(); } #endregion } } }
Problem With Basic Project
#1
Posted 14 August 2011 - 01:16 AM
#2
Posted 14 August 2011 - 05:26 AM
Since that method halts forever by a while-true loop, I would not call within a constructor. Any constructor should contain a quick initialization code, without heavy work (and event firing).
The:
webServer.ListenForRequest();pattern is correct.
Cheers
#3
Posted 14 August 2011 - 02:12 PM
You are calling the ListenForRequest method twice.
Since that method halts forever by a while-true loop, I would not call within a constructor. Any constructor should contain a quick initialization code, without heavy work (and event firing).
The:
webServer.ListenForRequest();pattern is correct.
Cheers
I will try that! I think that was from the example code. Just some other notes, it fails only about 1 out of 10 times when I have it attached to the debugger and I am using a static IP.
#4
Posted 14 August 2011 - 05:09 PM
I will try that! I think that was from the example code. Just some other notes, it fails only about 1 out of 10 times when I have it attached to the debugger and I am using a static IP.
No luck. I took it out of the constructor and I get the same results. It fails 3/4 times or so, it just does not give back a response. I'd like to fix this before continuing forward with my project.
#5
Posted 14 August 2011 - 11:28 PM
No luck. I took it out of the constructor and I get the same results. It fails 3/4 times or so, it just does not give back a response. I'd like to fix this before continuing forward with my project.
I thing its do someting width buffer size.
http://forums.netduino.com/index.php?/topic/2081-socketreceive-issue-with-receive-buffer-512-bytes-on-netduino-plus-411-beta-1/page__p__14938__hl__web__fromsearch__1#entry14938
#6
Posted 15 August 2011 - 12:00 AM
I thing its do someting width buffer size.
http://forums.netduino.com/index.php?/topic/2081-socketreceive-issue-with-receive-buffer-512-bytes-on-netduino-plus-411-beta-1/page__p__14938__hl__web__fromsearch__1#entry14938
I was only sending it a VERY small amount of data so I don't think applies. But I did switch to a threaded model and it fixed my issue. I don't think anyone will know this, but my LG tv can use only 3 pins in RS232 (RX, TX, and GRND) and it says it is UART, can I just use pins d0 + d1 as com1 and go right in without a shield?
#7
Posted 15 August 2011 - 12:20 AM
If the serial cable is RS232, that means that it uses signals which are up to -15V and 15V.I was only sending it a VERY small amount of data so I don't think applies. But I did switch to a threaded model and it fixed my issue. I don't think anyone will know this, but my LG tv can use only 3 pins in RS232 (RX, TX, and GRND) and it says it is UART, can I just use pins d0 + d1 as com1 and go right in without a shield?
The TTL serial port on Netduino uses voltages from 0V to 5V.
You'll want to use an RS232 level converter circuit or an RS232 shield. Otherwise you could damage your Netduino's microcontroller.
Chris
#8
Posted 15 August 2011 - 01:45 AM
#9
Posted 16 August 2011 - 08:40 AM
But I did switch to a threaded model and it fixed my issue.
oofki, do you mind posting the threaded code that is now working?
#10
Posted 17 August 2011 - 08:47 PM
oofki, do you mind posting the threaded code that is now working?
You got it!
Program.cs:
using System; using System.Net; using System.Net.Sockets; using System.Threading; using Microsoft.SPOT; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware; using SecretLabs.NETMF.Hardware.NetduinoPlus; using System.Text; using System.IO.Ports; namespace NetduinoPlusApplication1 { public class Program { public static OutputPort led; public static void Main() { led = new OutputPort(Pins.ONBOARD_LED, false); Listener webServer = new Listener(RequestReceived); webServer.StartListening(); } private static void RequestReceived(Request request) { if (request.URL.IndexOf("START") > 0) { led.Write(true); } else if (request.URL.IndexOf("STOP") > 0) { led.Write(false); } request.SendResponse("<html><body><p>Request from " + request.Client.ToString() + " received at " + DateTime.Now.ToString() + "</p><p>Method: " + request.Method + "<br />URL: " + request.URL +"</p></body></html>"); } } }
Listener.cs:
using System; using Microsoft.SPOT; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; using Microsoft.SPOT.Hardware; using SecretLabs.NETMF.Hardware.NetduinoPlus; namespace NetduinoPlusApplication1 { public delegate void RequestReceivedDelegate(Request request); public class Listener : IDisposable { const int maxRequestSize = 1024; readonly int portNumber = 80; private Socket listeningSocket = null; private RequestReceivedDelegate requestReceived; public Listener(RequestReceivedDelegate RequestReceived) : this(RequestReceived, 80) { } public Listener(RequestReceivedDelegate RequestReceived, int PortNumber) { portNumber = PortNumber; requestReceived = RequestReceived; listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listeningSocket.Bind(new IPEndPoint(IPAddress.Any, portNumber)); listeningSocket.Listen(10); new Thread(StartListening).Start(); } ~Listener() { Dispose(); } public void StartListening() { while (true) { using (Socket clientSocket = listeningSocket.Accept()) { IPEndPoint clientIP = clientSocket.RemoteEndPoint as IPEndPoint; Debug.Print("Received request from " + clientIP.ToString()); var x = clientSocket.RemoteEndPoint; int availableBytes = clientSocket.Available; Debug.Print(DateTime.Now.ToString() + " " + availableBytes.ToString() + " request bytes available"); int bytesReceived = (availableBytes > maxRequestSize ? maxRequestSize : availableBytes); if (bytesReceived > 0) { byte[] buffer = new byte[bytesReceived]; // Buffer probably should be larger than this. int readByteCount = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None); using (Request r = new Request(clientSocket, Encoding.UTF8.GetChars(buffer))) { Debug.Print(DateTime.Now.ToString() + " " + r.URL); if (requestReceived != null) requestReceived(r); } } } // I always like to have this in a continuous loop. Helps prevent lock-ups Thread.Sleep(10); } } #region IDisposable Members public void Dispose() { if (listeningSocket != null) listeningSocket.Close(); } #endregion } }
Request.cs:
using System; using Microsoft.SPOT; using System.Net.Sockets; using System.Text; using System.Net; using System.IO; namespace NetduinoPlusApplication1 { /// <summary> /// Holds information about a web request /// </summary> /// <remarks> /// Will expand as required, but stay simple until needed. /// </remarks> public class Request : IDisposable { private string method; private string url; private Socket client; const int fileBufferSize = 256; internal Request(Socket Client, char[] Data) { client = Client; ProcessRequest(Data); } /// <summary> /// Request method /// </summary> public string Method { get { return method; } } /// <summary> /// URL of request /// </summary> public string URL { get { return url; } } /// <summary> /// Client IP address /// </summary> public IPAddress Client { get { IPEndPoint ip = client.RemoteEndPoint as IPEndPoint; if (ip != null) return ip.Address; return null; } } /// <summary> /// Send a response back to the client /// </summary> /// <param name="response"></param> public void SendResponse(string response, string type = "text/html") { if (client != null) { string header = "HTTP/1.0 200 OK\r\nContent-Type: " + type + "; charset=utf-8\r\nContent-Length: " + response.Length.ToString() + "\r\nConnection: close\r\n\r\n"; client.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None); client.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None); Debug.Print("Response of " + response.Length.ToString() + " sent."); } } /// <summary> /// Sends a file back to the client /// </summary> /// <remarks> /// Assumes the application using this has checked whether it exists /// </remarks> /// <param name="filePath"></param> public void SendFile(string filePath) { // Map the file extension to a mime type string type = ""; int dot = filePath.LastIndexOf('.'); if (dot != 0) switch (filePath.Substring(dot + 1)) { case "css": type = "text/css"; break; case "xml": case "xsl": type = "text/xml"; break; case "jpg": case "jpeg": type = "image/jpeg"; break; case "gif": type = "image/gif"; break; // Not exhaustive. Extend this list as required. } using (FileStream inputStream = new FileStream(filePath, FileMode.Open)) { // Send the header string header = "HTTP/1.0 200 OK\r\nContent-Type: " + type + "; charset=utf-8\r\nContent-Length: " + inputStream.Length.ToString() + "\r\nConnection: close\r\n\r\n"; client.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None); byte[] readBuffer = new byte[fileBufferSize]; while (true) { // Send the file a few bytes at a time int bytesRead = inputStream.Read(readBuffer, 0, readBuffer.Length); if (bytesRead == 0) break; client.Send(readBuffer, bytesRead, SocketFlags.None); Debug.Print("Sending " + readBuffer.Length.ToString() + "bytes..."); } } Debug.Print("Sent file " + filePath); } /// <summary> /// Send a Not Found response /// </summary> public void Send404() { string header = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"; if (client != null) client.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None); Debug.Print("Sent 404 Not Found"); } /// <summary> /// Process the request header /// </summary> /// <param name="data"></param> private void ProcessRequest(char[] data) { string content = new string(data); string firstLine = content.Substring(0, content.IndexOf('\n')); // Parse the first line of the request: "GET /path/ HTTP/1.1" string[] words = firstLine.Split(' '); method = words[0]; url = words[1]; // Could look for any further headers in other lines of the request if required (e.g. User-Agent, Cookie) } #region IDisposable Members public void Dispose() { if (client != null) { client.Close(); client = null; } } #endregion } }
#11
Posted 19 August 2011 - 07:41 AM
#12
Posted 19 August 2011 - 03:17 PM
#13
Posted 19 August 2011 - 09:08 PM
#14
Posted 24 August 2011 - 09:07 PM
Running this exact code on the web server side, I get no more than 2 hours out, before becoming completely unresponsive.
I'm wandering if it's a RAM issue (I have ~30KB free at any time)
Hmm haven't checked mine in days until now and it still works I'm running 4.2RC1 all around. The only difference I can think of is I'm using a static ip, are you?
#15
Posted 25 August 2011 - 04:20 AM
#16
Posted 25 August 2011 - 08:37 PM
I'm using a static IP as well. Only thing I am left thinking is that it has something to do with the fact that we have 3 netduino's on the same LAN?
All different statically assigned IPs, all with their correct MACs set.
Whatttt!! How about using 4.2RC1? I think there was a GC bug in 4.1 from what I've read.
#17
Posted 25 August 2011 - 08:55 PM
Whatttt!! How about using 4.2RC1? I think there was a GC bug in 4.1 from what I've read.
Have two of them on 4.2RC1, one is still on 4.1. All 3 have the same issue.
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users