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