EDN Admin
Well-known member
I am trying to use an Asynchronous HTTPListener to create a simple web server in VB .Net (Not ASP) This will be run as a desktop application. My only goal is to be able to request Server Variables from the client. Is there any way to do this from within
a HTTPListenerWebServer? I am using the code from the MSDN VB .Net Samples:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; Imports System
<span style="color:Blue; Imports System.Collections.Generic
<span style="color:Blue; Imports System.ComponentModel
<span style="color:Blue; Imports System.Data
<span style="color:Blue; Imports System.Drawing
<span style="color:Blue; Imports System.Text
<span style="color:Blue; Imports System.Threading
<span style="color:Blue; Imports System.Windows.Forms
<span style="color:Blue; Imports System.Net
_
<span style="color:Blue; Class Form1
<span style="color:Blue; Dim t <span style="color:Blue; As Thread
<span style="color:Green;
<span style="color:Green; Direct the server to stop processing and exit the app
<span style="color:Green;
<span style="color:Blue; Private <span style="color:Blue; Sub button1_Click(<span style="color:Blue; ByVal sender <span style="color:Blue; As <span style="color:Blue; Object, <span style="color:Blue; ByVal e <span style="color:Blue; As EventArgs) <span style="color:Blue; Handles button1.Click
runServer = <span style="color:Blue; False
t.Abort()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; button1_Click
<span style="color:Green; Once the form is loaded, start a thread to spin up HttpListener
<span style="color:Green; We need to run a separate thread to co-exist with windows forms
<span style="color:Blue; Private <span style="color:Blue; Sub Form1_Load(<span style="color:Blue; ByVal sender <span style="color:Blue; As <span style="color:Blue; Object, <span style="color:Blue; ByVal e <span style="color:Blue; As EventArgs) <span style="color:Blue; Handles <span style="color:Blue; MyBase.Load
<span style="color:Green; Create the listener and direct it to localhost requests on port 8080
t = <span style="color:Blue; New Thread(<span style="color:Blue; New ThreadStart(<span style="color:Blue; AddressOf Start))
t.Start()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; Form1_Load
<span style="color:Green; Thread method to create the listener and direct it to localhost requests on port 8080
<span style="color:Blue; Private <span style="color:Blue; Sub Start()
AsynchronousListener(<span style="color:Blue; New <span style="color:Blue; String() {<span style="color:#A31515; "http://localhost:8080/"})
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; Start
<span style="color:Green; Flag indicating the server should continue processing requests.
<span style="color:Blue; Public <span style="color:Blue; Shared runServer <span style="color:Blue; As <span style="color:Blue; Boolean = <span style="color:Blue; True
<span style="color:Green; Delegate to allow cross-thread update of UI safely
<span style="color:Blue; Delegate <span style="color:Blue; Sub InvokeControl(<span style="color:Blue; ByVal [text] <span style="color:Blue; As <span style="color:Blue; String)
<span style="color:Blue; Private <span style="color:Blue; Shared listener <span style="color:Blue; As HttpListener
<span style="color:Green; Asynchronous HTTP listener. Instantiates and starts the HttpListener class,
<span style="color:Green; adds the prefix URIs to listen for, and enters the asynchronous processing loop
<span style="color:Green; until the runServer flag is set false.
<span style="color:Green; Param name prefixes is the URI prefix array to which the server responds
<span style="color:Blue; Public <span style="color:Blue; Sub AsynchronousListener(<span style="color:Blue; ByVal prefixes() <span style="color:Blue; As <span style="color:Blue; String)
<span style="color:Green; spin up listener
listener = <span style="color:Blue; New HttpListener()
<span style="color:Green; add URI prefixes to listen for
<span style="color:Blue; Dim s <span style="color:Blue; As <span style="color:Blue; String
<span style="color:Blue; For <span style="color:Blue; Each s <span style="color:Blue; In prefixes
listener.Prefixes.Add(s)
<span style="color:Blue; Next s
listener.Start()
<span style="color:Green; Create the delegate using the method to update the UI
<span style="color:Blue; Dim _invokeControl <span style="color:Blue; As <span style="color:Blue; New InvokeControl(<span style="color:Blue; AddressOf InvokeUIThread)
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Entering request processing loop")
<span style="color:Blue; While runServer
<span style="color:Blue; Dim result <span style="color:Blue; As IAsyncResult = listener.BeginGetContext(<span style="color:Blue; New AsyncCallback(<span style="color:Blue; AddressOf AsynchronousListenerCallback), listener)
<span style="color:Green; intermediate work can go on here while waiting for the asynchronous callback
<span style="color:Green; an asynchronous wait handle is used to prevent this thread from terminating
<span style="color:Green; while waiting for the asynchronous operation to complete.
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Waiting for asyncronous request processing.")
result.AsyncWaitHandle.WaitOne()
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Asynchronous request processed.")
<span style="color:Blue; End <span style="color:Blue; While
<span style="color:Green; If the runServer flag gets set to false, stop the server and close the listener.
listener.Close()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; AsynchronousListener
<span style="color:Green; / In order to safely update the UI across threads, a delegate with this method is
<span style="color:Green; / called using Control.Invoke
<span style="color:Blue; Private <span style="color:Blue; Shared <span style="color:Blue; Sub InvokeUIThread(<span style="color:Blue; ByVal [text] <span style="color:Blue; As <span style="color:Blue; String)
form1.listBox1.Items.Add([text])
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; InvokeUIThread
<span style="color:Green; Method called back when a client connects. BeginGetContext contains the AsynchCallback delegate
<span style="color:Green; for this method.
<span style="color:Green; param name result is the state object containing the HttpListener instance
<span style="color:Blue; Public <span style="color:Blue; Sub AsynchronousListenerCallback(<span style="color:Blue; ByVal result <span style="color:Blue; As IAsyncResult)
<span style="color:Blue; Try
<span style="color:Blue; Dim listener <span style="color:Blue; As HttpListener = <span style="color:Blue; CType(result.AsyncState, HttpListener)
<span style="color:Green; Call EndGetContext to signal the completion of the asynchronous operation.
<span style="color:Blue; Dim context <span style="color:Blue; As HttpListenerContext = listener.EndGetContext(result)
<span style="color:Blue; Dim request <span style="color:Blue; As HttpListenerRequest = context.Request
<span style="color:Green; Get the response object to send our confirmation.
<span style="color:Blue; Dim response <span style="color:Blue; As HttpListenerResponse = context.Response
<span style="color:Green; Construct a minimal response string.
<span style="color:Blue; Dim responseString <span style="color:Blue; As <span style="color:Blue; String = <span style="color:#A31515; "<HTML><BODY><H1>You have contacted an HttpListener web server</H1></BODY></HTML>"
<span style="color:Blue; Dim buffer <span style="color:Blue; As <span style="color:Blue; Byte() = System.Text.Encoding.UTF8.GetBytes(responseString)
<span style="color:Green; Get the response OutputStream and write the response to it.
response.ContentLength64 = buffer.Length
<span style="color:Green; Identify the content type.
response.ContentType = <span style="color:#A31515; "text/html"
<span style="color:Blue; Dim output <span style="color:Blue; As System.IO.Stream = response.OutputStream
output.Write(buffer, 0, buffer.Length)
<span style="color:Green; Properly flush and close the output stream
output.Flush()
output.Close()
<span style="color:Blue; Catch ex <span style="color:Blue; As Exception
Application.<span style="color:Blue; Exit()
<span style="color:Blue; End <span style="color:Blue; Try
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; AsynchronousListenerCallback
<span style="color:Blue; Private <span style="color:Blue; Sub Form1_FormClosing(<span style="color:Blue; ByVal sender <span style="color:Blue; As System.Object, <span style="color:Blue; ByVal e <span style="color:Blue; As System.Windows.Forms.FormClosingEventArgs) <span style="color:Blue; Handles <span style="color:Blue; MyBase.FormClosing
runServer = <span style="color:Blue; False
t.Abort()
<span style="color:Blue; End <span style="color:Blue; Sub
<span style="color:Blue; End <span style="color:Blue; Class <span style="color:Green; Form1
[/code]
MSDN states I should use System.Web.HttpRequest.ServerVariables but that seems to be unavailable outside of ASP. Any suggestions?
View the full article
a HTTPListenerWebServer? I am using the code from the MSDN VB .Net Samples:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; Imports System
<span style="color:Blue; Imports System.Collections.Generic
<span style="color:Blue; Imports System.ComponentModel
<span style="color:Blue; Imports System.Data
<span style="color:Blue; Imports System.Drawing
<span style="color:Blue; Imports System.Text
<span style="color:Blue; Imports System.Threading
<span style="color:Blue; Imports System.Windows.Forms
<span style="color:Blue; Imports System.Net
_
<span style="color:Blue; Class Form1
<span style="color:Blue; Dim t <span style="color:Blue; As Thread
<span style="color:Green;
<span style="color:Green; Direct the server to stop processing and exit the app
<span style="color:Green;
<span style="color:Blue; Private <span style="color:Blue; Sub button1_Click(<span style="color:Blue; ByVal sender <span style="color:Blue; As <span style="color:Blue; Object, <span style="color:Blue; ByVal e <span style="color:Blue; As EventArgs) <span style="color:Blue; Handles button1.Click
runServer = <span style="color:Blue; False
t.Abort()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; button1_Click
<span style="color:Green; Once the form is loaded, start a thread to spin up HttpListener
<span style="color:Green; We need to run a separate thread to co-exist with windows forms
<span style="color:Blue; Private <span style="color:Blue; Sub Form1_Load(<span style="color:Blue; ByVal sender <span style="color:Blue; As <span style="color:Blue; Object, <span style="color:Blue; ByVal e <span style="color:Blue; As EventArgs) <span style="color:Blue; Handles <span style="color:Blue; MyBase.Load
<span style="color:Green; Create the listener and direct it to localhost requests on port 8080
t = <span style="color:Blue; New Thread(<span style="color:Blue; New ThreadStart(<span style="color:Blue; AddressOf Start))
t.Start()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; Form1_Load
<span style="color:Green; Thread method to create the listener and direct it to localhost requests on port 8080
<span style="color:Blue; Private <span style="color:Blue; Sub Start()
AsynchronousListener(<span style="color:Blue; New <span style="color:Blue; String() {<span style="color:#A31515; "http://localhost:8080/"})
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; Start
<span style="color:Green; Flag indicating the server should continue processing requests.
<span style="color:Blue; Public <span style="color:Blue; Shared runServer <span style="color:Blue; As <span style="color:Blue; Boolean = <span style="color:Blue; True
<span style="color:Green; Delegate to allow cross-thread update of UI safely
<span style="color:Blue; Delegate <span style="color:Blue; Sub InvokeControl(<span style="color:Blue; ByVal [text] <span style="color:Blue; As <span style="color:Blue; String)
<span style="color:Blue; Private <span style="color:Blue; Shared listener <span style="color:Blue; As HttpListener
<span style="color:Green; Asynchronous HTTP listener. Instantiates and starts the HttpListener class,
<span style="color:Green; adds the prefix URIs to listen for, and enters the asynchronous processing loop
<span style="color:Green; until the runServer flag is set false.
<span style="color:Green; Param name prefixes is the URI prefix array to which the server responds
<span style="color:Blue; Public <span style="color:Blue; Sub AsynchronousListener(<span style="color:Blue; ByVal prefixes() <span style="color:Blue; As <span style="color:Blue; String)
<span style="color:Green; spin up listener
listener = <span style="color:Blue; New HttpListener()
<span style="color:Green; add URI prefixes to listen for
<span style="color:Blue; Dim s <span style="color:Blue; As <span style="color:Blue; String
<span style="color:Blue; For <span style="color:Blue; Each s <span style="color:Blue; In prefixes
listener.Prefixes.Add(s)
<span style="color:Blue; Next s
listener.Start()
<span style="color:Green; Create the delegate using the method to update the UI
<span style="color:Blue; Dim _invokeControl <span style="color:Blue; As <span style="color:Blue; New InvokeControl(<span style="color:Blue; AddressOf InvokeUIThread)
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Entering request processing loop")
<span style="color:Blue; While runServer
<span style="color:Blue; Dim result <span style="color:Blue; As IAsyncResult = listener.BeginGetContext(<span style="color:Blue; New AsyncCallback(<span style="color:Blue; AddressOf AsynchronousListenerCallback), listener)
<span style="color:Green; intermediate work can go on here while waiting for the asynchronous callback
<span style="color:Green; an asynchronous wait handle is used to prevent this thread from terminating
<span style="color:Green; while waiting for the asynchronous operation to complete.
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Waiting for asyncronous request processing.")
result.AsyncWaitHandle.WaitOne()
listBox1.Invoke(_invokeControl, <span style="color:#A31515; "Asynchronous request processed.")
<span style="color:Blue; End <span style="color:Blue; While
<span style="color:Green; If the runServer flag gets set to false, stop the server and close the listener.
listener.Close()
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; AsynchronousListener
<span style="color:Green; / In order to safely update the UI across threads, a delegate with this method is
<span style="color:Green; / called using Control.Invoke
<span style="color:Blue; Private <span style="color:Blue; Shared <span style="color:Blue; Sub InvokeUIThread(<span style="color:Blue; ByVal [text] <span style="color:Blue; As <span style="color:Blue; String)
form1.listBox1.Items.Add([text])
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; InvokeUIThread
<span style="color:Green; Method called back when a client connects. BeginGetContext contains the AsynchCallback delegate
<span style="color:Green; for this method.
<span style="color:Green; param name result is the state object containing the HttpListener instance
<span style="color:Blue; Public <span style="color:Blue; Sub AsynchronousListenerCallback(<span style="color:Blue; ByVal result <span style="color:Blue; As IAsyncResult)
<span style="color:Blue; Try
<span style="color:Blue; Dim listener <span style="color:Blue; As HttpListener = <span style="color:Blue; CType(result.AsyncState, HttpListener)
<span style="color:Green; Call EndGetContext to signal the completion of the asynchronous operation.
<span style="color:Blue; Dim context <span style="color:Blue; As HttpListenerContext = listener.EndGetContext(result)
<span style="color:Blue; Dim request <span style="color:Blue; As HttpListenerRequest = context.Request
<span style="color:Green; Get the response object to send our confirmation.
<span style="color:Blue; Dim response <span style="color:Blue; As HttpListenerResponse = context.Response
<span style="color:Green; Construct a minimal response string.
<span style="color:Blue; Dim responseString <span style="color:Blue; As <span style="color:Blue; String = <span style="color:#A31515; "<HTML><BODY><H1>You have contacted an HttpListener web server</H1></BODY></HTML>"
<span style="color:Blue; Dim buffer <span style="color:Blue; As <span style="color:Blue; Byte() = System.Text.Encoding.UTF8.GetBytes(responseString)
<span style="color:Green; Get the response OutputStream and write the response to it.
response.ContentLength64 = buffer.Length
<span style="color:Green; Identify the content type.
response.ContentType = <span style="color:#A31515; "text/html"
<span style="color:Blue; Dim output <span style="color:Blue; As System.IO.Stream = response.OutputStream
output.Write(buffer, 0, buffer.Length)
<span style="color:Green; Properly flush and close the output stream
output.Flush()
output.Close()
<span style="color:Blue; Catch ex <span style="color:Blue; As Exception
Application.<span style="color:Blue; Exit()
<span style="color:Blue; End <span style="color:Blue; Try
<span style="color:Blue; End <span style="color:Blue; Sub <span style="color:Green; AsynchronousListenerCallback
<span style="color:Blue; Private <span style="color:Blue; Sub Form1_FormClosing(<span style="color:Blue; ByVal sender <span style="color:Blue; As System.Object, <span style="color:Blue; ByVal e <span style="color:Blue; As System.Windows.Forms.FormClosingEventArgs) <span style="color:Blue; Handles <span style="color:Blue; MyBase.FormClosing
runServer = <span style="color:Blue; False
t.Abort()
<span style="color:Blue; End <span style="color:Blue; Sub
<span style="color:Blue; End <span style="color:Blue; Class <span style="color:Green; Form1
[/code]
MSDN states I should use System.Web.HttpRequest.ServerVariables but that seems to be unavailable outside of ASP. Any suggestions?
View the full article