@ ChrisK: thanks for the hint. For me it is not an acceptable solution to provide a webserver without caching sockets, because each usual website uses a favicon, css files, images … which are loaded afterwards and these requests fail, because the browsers requests it fast and parallel.
But I tested it anyway. And it doesn’t work as expected.
As you can see in the test code there is an additional thread to test, whether the listener is still working, knowing, that it requires an additional socked.
First test:
not using the monitor thread, i.e. it’s the simplest (!) webserver I could imagine and I would expect that it runs. Otherwise NETMF is not an option for me, but I cannot believe, that we are the first one building a webserver and GHI will not find a solution. Is there nobody having a simple webserver up and running (than please post the code)?
Result: After some (not very fast) refreshes it hangs, maybe because the browser tries to get the icon…
Second test: If the monitor is active (interval = 1000ms), it seems to be working, but after some requests (~20) it hangs, too.
Third test: increasing the interval to 3000ms, no changes, especially if there are additional requests from the real browser (using chrome).
@ GHI: I investigated so much time and have a project, which absolutely requires a usual webserver. I tried some samples, tried gadgeteer, bought new hardware twice (!) (Panda2 -> G120 -> Raptor) and I cannot use it. Sorry, but I’m at a point where I want to throw it all away and start with some other hardware, but I already investigated so much time and money (my wife will kill me
, and hopefully she is not doing the next post
)
Please, please help to get such a basic functionality up and running.
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT.Hardware;
using GHI.Pins;
using System.Net.Sockets;
using System.Net;
namespace HC
{
public partial class Program
{
private DateTime StartTime;
private int timeout = 5;
private int count = 0;
void ProgramStarted()
{
StartTime = DateTime.Now;
Debug.Print("Program Started");
ethernetENC28.NetworkInterface.EnableStaticIP("192.168.1.14", "255.255.255.0", "192.168.1.1");
ethernetENC28.NetworkUp += ethernetENC28_NetworkUp;
GT.Timer timer = new GT.Timer(1000);
timer.Tick += MainThread;
timer.Start();
}
void ethernetENC28_NetworkUp(GT.Modules.Module.NetworkModule sender, GT.Modules.Module.NetworkModule.NetworkState state)
{
Debug.Print("IP:" + ethernetENC28.NetworkSettings.IPAddress.ToString());
StartTime = DateTime.Now;
var workerThread = new Thread(this.Listen);
workerThread.Start();
//var monitorThread = new Thread(this.Monitor);
//monitorThread.Start();
}
void MainThread(Gadgeteer.Timer timer)
{
//...
}
private void Listen()
{
const Int32 c_port = 80;
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, c_port);
server.Bind(localEndPoint);
server.Listen(0); // <---- changed to 0
while (true)
{
Socket clientSocket = server.Accept();
Debug.Print("Webserver Request (" + this.count++.ToString() + "): " + clientSocket.RemoteEndPoint);
using (clientSocket)
{
Byte[] buffer = new Byte[1024];
if (clientSocket.Poll(5000 * 1000, SelectMode.SelectRead))
{
if (clientSocket.Available != 0)
{
Int32 bytesRead = clientSocket.Receive(buffer, clientSocket.Available, SocketFlags.None);
TimeSpan ts = DateTime.Now - StartTime;
String s =
"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<html><head><title>.NET Micro Framework Web Server</title></head>" +
"<body><bold><h1>REAPTOR:<br>running since: " + ts.ToString() + "<br>Count: " + this.count.ToString() +"</h1></bold></body></html>";
clientSocket.Send(System.Text.Encoding.UTF8.GetBytes(s));
}
clientSocket.Close();
}
}
Debug.GC(true);
}
}
private void Monitor()
{
TimeSpan timeout = new TimeSpan(0, 0, this.timeout);
while (true)
{
Thread.Sleep(3000);
var pingThread = new Thread(this.Ping);
pingThread.Start();
DateTime start = DateTime.Now;
while ((DateTime.Now - start) < timeout && pingThread.IsAlive)
{
Thread.Sleep(1000);
}
if (pingThread.IsAlive)
{
Debug.Print(">>>>> REBOOT <<<<<");
//Microsoft.SPOT.Hardware.PowerState.RebootDevice(true);
}
else
{
Debug.Print("NO PING TIMEOUT - " + this.count.ToString());
}
}
}
private void Ping()
{
string hostName = "127.0.0.1";
int hostPort = 80;
IPAddress host = IPAddress.Parse(hostName);
IPEndPoint hostep = new IPEndPoint(host, hostPort);
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
string GETrequest = "ping";
socket.Connect(hostep);
try
{
socket.Send(System.Text.Encoding.UTF8.GetBytes(GETrequest));
if (socket.Poll(3000, SelectMode.SelectRead))
{
int requiredBufferSize = socket.Available;
if (requiredBufferSize != 0)
{
byte[] Buffer = new byte[requiredBufferSize];
int requestLength = socket.Receive(Buffer);
if (requestLength > 0)
{
char[] c = System.Text.Encoding.UTF8.GetChars(Buffer);
string text = new string(c);
Debug.Print(text);
}
}
}
}
catch
{
Thread.Sleep(timeout * 2000);
}
socket.Close();
Debug.GC(true);
}
}
}
}