Netduino Plus 2 Web Server - Netduino Plus 2 (and Netduino Plus 1) - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino Plus 2 Web Server


  • Please log in to reply
8 replies to this topic

#1 marksmanaz

marksmanaz

    Member

  • Members
  • PipPip
  • 15 posts

Posted 09 May 2013 - 07:14 PM

Hello Everybody,

I am attempting to create a web server that will allow me to interact with the I/O ports on the Netduino Plus 2 via the internet and Twilio. The code below is my "Hello World!" to get started. I am using VB because its just my thing. I have pieced this together but I have three issues that have stalled me for two days now and I am seeking assistance. Any help is greatly appreciated. At the end I will attach any images that I feel may help in the investigation.

 

  The code below works fine when I bring up the Netduino on any local computer's browser. It gives the response "Hello World!" along with the IP address. The first problem I have is that my Netduino Plus 2 will not accept a request from a computer not on the local network. The debug output gives nothing when a request comes in from the outside. But the remote browser says connection was closed before data was received by the server. It seems to just all out ignore the requests. I would like in the future to be able to only have it accept request from designated IP for security but for now it won’t work with any WAN originated IP.

I have opened up several different ports on the router and forward them to the Netduino. I have reserved an IP address on my router by mac address using DHCP and have tried several different IPs to make sure there wasn't any other device on the network with the same IP to conflict with it. I can ping the unit from the LAN and the unit accepts requests from the LAN. It will not accept any requests from the outside including over a VPN connection.

It seems as though the Netduino does not know how to respond to packets from and through a router. I tried addressing the request using the IP (XXX.XXX.XXX.XXX:5589) and by using a DDNS (myddnsdomain.com:5580) and I get the same result. I have tried two routers; one a dd-wrt based router and one that is not. I did setup a small web server on my Windows machine and forward all the same ports to it and it handles request and sends data to and from the Internet just fine.

I have erased the Netduino and flash the 4.2.2.2 firmware again and redeployed the project again with same results. I commented out as much as the code that I could so that it would only accept requests and nothing else. The local requests would error in the browsers saying connection accepted but no response given while WAN requests still say connection closed by server before data sent.

My second problem and may be a clue to the first is at some point I started getting these warnings in the build that originally were not there and I am not sure what they mean but may be a clue.

Warning  1  opcode 'sub.ovf' -- overflow will not throw exception …WebServer.vb 44 33 WebServerHelloWorrld

This refers to this line where “buffer” is declared.

Dim buffer As Byte() = New Byte(bytesReceived - 1) {}

The third problem is that on Chrome and IE when a request is made it seems to send the request twice so it turns the light on and off twice at 5 second blocks. The two complete requests show in debug. Firefox seems to handle it ok except when I do a refresh then the post back creates two requests but all the browsers seem to double request on a post back. This also may be related to the other two but I was thinking the browsers are sending a second request because the response from the web server is not formatted right or data is incomplete.

Please look over it and let me know what I could do to remedy these. My priority is to get the web server to respond to WAN requests so that I may start interacting with Twilio.

 

Thank you for your time,

 

Mark

 

 

 

Module1.vb

Imports Microsoft.SPOTImports Microsoft.SPOT.HardwareImports SecretLabs.NETMF.HardwareImports SecretLabs.NETMF.Hardware.NetduinoPlusModule Module1    Sub Main()	    ' write your code here	    Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()(0).EnableDhcp()	    Dim webServer As New WebServerHelloWorrld.WebServer()	    webServer.ListenForRequest()    End SubEnd Module

WebServer.vb

Imports Microsoft.SPOTImports System.Net.SocketsImports System.NetImports System.ThreadingImports System.TextImports Microsoft.SPOT.HardwareImports SecretLabs.NETMF.HardwareImports SecretLabs.NETMF.Hardware.NetduinoPlusNamespace WebServerHelloWorrld    Public Class WebServer        Implements IDisposable        Private listeningSocket As Socket = Nothing        'open connection to onbaord led so we can blink it with every request        Private led As New OutputPort(Pins.GPIO_PIN_D0, True)        Public Sub New()            'Initialize Socket class            listeningSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)            'Request and bind to an IP from DHCP server            listeningSocket.Bind(New IPEndPoint(IPAddress.Any, 5580))            'Debug print our IP address            Debug.Print(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()(0).IPAddress)            'Start listen for web requests            listeningSocket.Listen(10)        End Sub        Public Sub ListenForRequest()            Try                While True                    Using clientSocket As Socket = listeningSocket.Accept()                        'Get clients IP                        Dim clientIP As IPEndPoint = TryCast(clientSocket.RemoteEndPoint, IPEndPoint)                        Dim clientEndPoint As EndPoint = clientSocket.RemoteEndPoint                        Dim bytesReceived As Integer = clientSocket.Available                        If bytesReceived > 0 Then                            'Get request                            Dim buffer As Byte() = New Byte(bytesReceived - 1) {}                            Dim byteCount As Integer = clientSocket.Receive(buffer, bytesReceived, SocketFlags.None)                            Dim request As New String(Encoding.UTF8.GetChars(buffer))                            Debug.Print(request)                            'Compose a response                            Dim response As String = "Hello World!" & " " & clientIP.ToString                            Dim header As String = ""                            header = "HTTP/1.1 200 OK" & Constants.vbCr & Constants.vbLf & "Server: Netduino" & Constants.vbCr & Constants.vbLf & "Pragma : no-cache" & Constants.vbCr & Constants.vbLf & "Content-Type: text/html;charset=UTF-8" & Constants.vbCr & Constants.vbLf & "Cache-Control: no-cache" & Constants.vbCr & Constants.vbLf & "Content-Length: " & response.Length.ToString() & Constants.vbCr & Constants.vbLf & "Connection: close" & Constants.vbCr & Constants.vbLf & Constants.vbCr & Constants.vbLf                            clientSocket.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None)                            clientSocket.Send(Encoding.UTF8.GetBytes(response), response.Length, SocketFlags.None)                            'Blink the onboard LED                            led.Write(False)                            Thread.Sleep(5000)                            led.Write(True)                            Debug.Print("Success")                        End If                    End Using                End While                Thread.Sleep(500)            Catch ex As Exception                Debug.Print(ex.ToString)            End Try        End Sub#Region "IDisposable Members"        Protected Overrides Sub Finalize()            Try                Dispose()            Finally                MyBase.Finalize()            End Try        End Sub        Public Sub Dispose() Implements IDisposable.Dispose            If listeningSocket Is Nothing Then                listeningSocket.Close()            End If        End Sub#End Region    End ClassEnd Namespace

Posted Image

 

Posted Image



#2 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 10 May 2013 - 02:13 AM

Your first problem initially sounded as if you forgot port forwarding on your router, but then I gather you've done that. Thing is, the Netduino basically shouldn't treat the requests anymdifferently in either case or even tell the difference. What about opening up the corresponding router port for incoming requests? As I get it, your webserver never even sees the requests which would of course suggest that it is blocked prior to getting that far. The twice-problem is likely an initial request for "/favicon.ico" and then the intended request. Debug.Print the url header and you'll hopefully see what I mean. In case you didn't know, browsers use favicon.ico to add an image in the top left corner of their window much like most windows apps do. I wouldn't worry about the warning, you could also write "byte(0 to len)" which would be less confusing due to the unorthodox array indexing of VB. Hopefully, it's now atleast one down and two to go :-)

#3 marksmanaz

marksmanaz

    Member

  • Members
  • PipPip
  • 15 posts

Posted 11 May 2013 - 06:13 AM

hanzibal,

Thank you for your reply. I appreciate all input. I tried your suggestion and added "byte(0 to len)" but that created an error: "Array bounds cannot appear in type specifiers". It does appear that the "/favicon.ico" is causing the double requests and I should be able to handle that when the time comes.

As far as my issue with requests not being accepted from a remote computers that is still not resolved. I can say that it has nothing to do with anything on my network "blocking" the request. I plugged the Netduino in directly to my cable modem rebooted both and the Netduino took a IP address that put it on the internet directly with no middle man. I then sent request to that IP and still did not get a request or anything showing that a request was made in debug.

I did discover that if I repeatedly click refresh on any of the remote browsers rapidly about a dozen times it would finally respond once of the twelve requests. This proving that the request are getting to the Netduino.

I then down graded from firmware 4.2.2.2 to 4.2.1.1 and noticed that there was a improvement in how many times I could get a response when rapidly clicking the refresh button and throwing as many request at the Netduino as I could. I would say 4.2.1.1 would respond 4 or 5 times out of 12 instead of 1 out of 12. Of course this still is not acceptable in any application.

        I have concluded that there is a bug in the Netduino Plus 2 that will not consistently address requests outside its own sub net. It would be helpful if anyone could confirm this with their Netduino Plus 2 using firmware 4.2.2.2  and the above code. If no one can confirm or refute this I will formally submit a bug report based on my findings.

 

Thank you,

 

Mark



#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 12 May 2013 - 07:20 PM

I just had another look at your code and I see that you check Available before doing anything at all. Maybe you have changed that now, but I think Available can be zero which just means that no data has been read in advance for you and that you must read it all by yourself - there's still an incoming request to be serviced. If not already done, put a Debug.Print statement immediately after the Accept statement and see what happens.



#5 marksmanaz

marksmanaz

    Member

  • Members
  • PipPip
  • 15 posts

Posted 16 May 2013 - 06:30 AM

 hanzibal,

  Thanks for looking it over again; I appreciate it very much. As I stated I do receive and it acknowledges requests from internal request on the same sub net and does nothing for request on the other side of a router either by VPN or direct. Maybe my thinking is wrong but if it picks up the request from the LAN then it should not discriminate from WAN requests through a router and changing where it checks available is moot since it does acknowledge internal request.

Well as it turned out this forced me to make a decision moving forward with this project. I have come to the conclusion that my Netduino Plus 2 is defective in some way preventing it from accepting request from outside its local network. I am guessing that this is a firmware issue with 4.2 and only because no one else has confirmed either way if they have the same issue as I do or that it works fine for them. I can't imagine it being a hardware issue but who knows. So I had to make a decision either to return my unit and wait for the replacement and continue along my original plans to have request go to the Netduino directly or keep the unit and use a "relay web server" on a PC on the same LAN sub net that can accept the request and forward them to the Netduino and then receive and forward the response to the origin of the request in my case this being Twilio.

 

Now I had thought about going down this road in the beginning before I came into this dilemma but decided against it for two reasons; first being the added expense of having to setup a computer as a web sever either dedicated or one being used already for some other purpose. The second being this would add another point of failure in the application. Now that I know that the Netduino can't communicate through a router  I re-thunk that option and I did setup a IIS web server and I am using an ASP.NET VB solution to receive the POST request from Twilio and send the command on to the netduino. The netduino processes the command (checking sensors firing outputs or what have you and sends the response to the IIS server in which returns the response to Twilio.

Using a "relay server" has two benefits; one it acts as a buffer between the netduino and the outside world and I have added code to the ASP solution that checks that the incoming request are coming from friendly sources there by actively making it more secure. Two it can handle a lot of the code work that would have been left to the netduino to do such as the security and I can store the responses on the IIS server so when the netduino checks sensors and instead of having code lines such as "This is my response string have a nice day" I have it send a decimal response 1,2,3,4 an so on. Then the IIS server goes through a select case and picks up the correlating response and returns it to Twilio.

It works very well and I have saved a lot of bytes from being stored on the netduino leaving room for other operations. I just had to pitch it to my client and sell him on the fact that it is more secure and leaves us with more options going forward.

 

Thanks again hanzibal and I will let you know how the finished project turns out.  For anyone else out there that has the NP2 I would be very interested in knowing if you can receive http commands through a router to your NP2 or are you having the same issue.

 

Thanks,

 

Mark



#6 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 16 May 2013 - 06:49 AM

Sounds like a good decision given the benefits you see in a relay server and the time invested in fruitless attempts to getting it working without one. Still, its remarkable that it does not work, I have such a hard time believing that requests via a router is treated any different that ones coming from a local network. Have you actually checked to make sure it has nothing todo with bytesAvaible? That is one thing that could be handeled differently. I agree, it would be very interesting to hear if others are experiening this issue.

#7 marksmanaz

marksmanaz

    Member

  • Members
  • PipPip
  • 15 posts

Posted 23 May 2013 - 04:30 AM

hanzibal,

  If you could elaborate on how to handle "bytesAvaible" with my above code I would like to see if that fixes the problem. I came upon a related issue that has convinced me to return the unit if this can't be resolved. I wanted to put this unit in a remote location and connect it to a wireless bridge as I did not have a cable in that location and guess what... it won't respond through the bridge just as it does not through a router. So if you give me a code sample that would correct the bytesAvaible I would appriciate it.

 

Thanks,

 

Mark



#8 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 23 May 2013 - 09:03 AM

It is this code snippet (taken from your code above) that I'm referring to:

Dim bytesReceived As Integer = clientSocket.AvailableIf bytesReceived > 0 Then...

Now, I'm not sure about how this works in the .NETMF (and Netduino) world, but in a Windows environment, clientSocket.Available would only contain the part of the data that is immediately available.

 

That is, clientSocket.Available does not necessarily contain the full request data (headers and such) but only some initial part of the data that has been pre-read for you by the framework at the point in time at which your listener receives the incoming request. The rest of the data you must read yourself by calling the corresponding read method on the socket. You can see clientSocket.Available as being a read-ahead buffer.

 

This means, that just because clientSocket.Available is zero, that does not mean that there's no request. I believe that clientSocket.Available would typically be more likely of be non-zero for requests coming from a LAN than from a WAN since the LAN would be faster. This could explain the issues your having with this.

 

I have a really hard time believing a h/w flaw is causing the problems you're experiencing.



#9 kash

kash

    New Member

  • Members
  • Pip
  • 6 posts

Posted 05 December 2015 - 06:26 PM

"Using a "relay server" has two benefits; one it acts as a buffer between the netduino and the outside world and I have added code to the ASP solution that checks that the incoming request are coming from friendly sources there by actively making it more secure. Two it can handle a lot of the code work that would have been left to the netduino to do such as the security and I can store the responses on the IIS server so when the netduino checks sensors and instead of having code lines such as "This is my response string have a nice day" I have it send a decimal response 1,2,3,4 an so on. Then the IIS server goes through a select case and picks up the correlating response and returns it to Twilio."

 

I am having the same problem. The Netduino sever works on LAN address but fails on public web access. Could you please share with me the relay code you wrote for IIS. Many thanks in advance,






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.