Resolved Httplistener serving HTML and images..

Hostium

Member
Joined
Jan 23, 2009
Messages
21
Programming Experience
Beginner
Hi guys, i'm really new to programming and VB.NET and i'm attempting to make myself a very simple web server using Httplistener. The code below works perfectly apart from the fact that i'm really not sure how to go about making it serve an image as well as the HTML on request.

I have an image called test.jpg in the same DIR as my application, can anybody point me in the right direction or show me how to make that image load - it shows up as a broken link image when the rest of the page loads.

Thank you...

VB.NET:
Imports System.Net.Sockets
Imports System.Text
Imports System.Net
Imports System.Globalization
Module HttpListener
    Sub Main()
        ProcessRequests()
    End Sub
    Private Sub ProcessRequests()
        If Not System.Net.HttpListener.IsSupported Then
            Console.WriteLine( _
            "Windows XP SP2, Server 2003, or higher is required to " & _
            "use the HttpListener class.")
            Exit Sub
        End If
        ' URI prefixes are required,
        ' Create a listener and add the prefixes.
        Dim listener As System.Net.HttpListener = _
        New System.Net.HttpListener()
        listener.Prefixes.Add("http://*:8001/")
        Try
            ' Start the listener to begin listening for requests.
            listener.Start()
            Console.WriteLine("Listening...")
            ' Set the number of requests this application will handle.
            Dim numRequestsToBeHandled As Integer = "20"
            For i As Integer = 0 To numRequestsToBeHandled
                Dim response As HttpListenerResponse = Nothing
                Try
                    ' Note: GetContext blocks while waiting for a request.
                    Dim context As HttpListenerContext = listener.GetContext()
                    ' Create the response.
                    response = context.Response
                    Dim responseString As String = _
                    "<HTML><BODY>The time is currently " & _
                    DateTime.Now.ToString( _
                    DateTimeFormatInfo.CurrentInfo) & _
                    "<img src=test.jpg>" & _
                    "</BODY></HTML>"
                    Dim buffer() As Byte = _
                    System.Text.Encoding.UTF8.GetBytes(responseString)
                    response.ContentLength64 = buffer.Length
                    Dim output As System.IO.Stream = response.OutputStream
                    output.Write(buffer, 0, buffer.Length)
                Catch ex As HttpListenerException
                    Console.WriteLine(ex.Message)
                Finally
                    If response IsNot Nothing Then
                        response.Close()
                    End If
                End Try
            Next
        Catch ex As HttpListenerException
            Console.WriteLine(ex.Message)
        Finally
            ' Stop listening for requests.
            listener.Close()
            Console.WriteLine("Done Listening...")
        End Try
    End Sub
End Module
 
Last edited:
This should get you started:
VB.NET:
Dim context As HttpListenerContext = listener.GetContext()                    
Dim file As String = context.Request.Url.LocalPath 'note: Uri could have query also
Console.WriteLine("requested: " & file)
response = context.Response                    
If file = "/" Then
    Dim responseString As String = "root response as posted"
    '...
Else
    file = System.AppDomain.CurrentDomain.BaseDirectory & file.Substring(1)
    If IO.File.Exists(file) Then
        Select Case IO.Path.GetExtension(file).ToLower
            Case ".htm", ".html"
                response.ContentType = Mime.MediaTypeNames.Text.Html
            Case Else
                response.ContentType = Mime.MediaTypeNames.Application.Octet
        End Select
        Dim content() As Byte = My.Computer.FileSystem.ReadAllBytes(file)
        response.ContentLength64 = content.Length
        response.OutputStream.Write(content, 0, content.Length)
    Else
        response.StatusCode = HttpStatusCode.NotFound
    End If
End If
 
Thanks John, this code is a lot better since you showed me how to load a html file instead of writing out the HTML in a string. It works and the html file i've created is outputting correctly but i'm still having the same issues with the jpg though, I changed this in the code...
VB.NET:
        Select Case IO.Path.GetExtension(file).ToLower
                                Case ".htm", ".html"
                                    response.ContentType = Mime.MediaTypeNames.Text.Html
                                Case ".jpg", ".jpeg"
                                    response.ContentType = Mime.MediaTypeNames.Image.Jpeg
                                Case Else
                                    response.ContentType = Mime.MediaTypeNames.Application.Octet
                            End Select

I also didn't know about mime types so I looked that up as well I thought that maybe the reason the image wasn't loading is because the mime type for it wasn't there, I added that in and i'm getting the same results, i'm sure you're not surprised.

Am I right in thinking that the reason the image isn't loading is because the response.OutputStream.Write(content, 0, content.Length) isn't getting the bytes from the image so it's not sending them with the request?
 
On a side note when I changed 'index.html' to 'test.jpg' the image is loading, so I feel like i'm getting somewhere, thank you...
 
I'm not sure if i'm on the right track here but this is what I have so far..

VB.NET:
   Dim context As HttpListenerContext = listener.GetContext()
                    Dim file As String = context.Request.Url.LocalPath
                    file = "/index.html"
                    Console.WriteLine("requested: " & file)
                    response = context.Response
                    If file = "/" Then
                        Dim responseString As String = "root response as posted"
                        '...
                    Else
                        file = System.AppDomain.CurrentDomain.BaseDirectory & file.Substring(1)
                        If IO.File.Exists(file) Then
                            Select Case IO.Path.GetExtension(file).ToLower
                                Case ".htm", ".html"
                                    response.ContentType = Mime.MediaTypeNames.Text.Html
                                Case ".jpg", ".jpeg"
                                    response.ContentType = Mime.MediaTypeNames.Image.Jpeg
                                Case Else
                                    response.ContentType = Mime.MediaTypeNames.Application.Octet
                            End Select
                            'Open Filestream to read bytes from image
                            Dim fStream As FileStream = New FileStream("test.jpg", FileMode.Open, FileAccess.Read)
                            'Get image bytes
                            Dim image As Byte() = New Byte(fStream.Length) {}
                            Dim content() As Byte = My.Computer.FileSystem.ReadAllBytes(file)
                            'Stream image into content array
                            fStream.Read(content, 0, image.Length)
                            response.ContentLength64 = content.Length
                            response.OutputStream.Write(content, 0, content.Length)
                        Else
                            response.StatusCode = HttpStatusCode.NotFound
                        End If
                    End If

I'm getting a .. "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection." exception on ..
VB.NET:
fStream.Read(content, 0, fStream.Length)

I'm really not sure what else to try..
 
Last edited:
I would remove all this code:
'Open Filestream to read bytes from image
Dim fStream As FileStream = New FileStream("test.jpg", FileMode.Open, FileAccess.Read)
'Get image bytes
Dim image As Byte() = New Byte(fStream.Length) {}
Dim content() As Byte = My.Computer.FileSystem.ReadAllBytes(file)
'Stream image into content array
fStream.Read(content, 0, fStream.Length)
response.ContentLength64 = content.Length
response.OutputStream.Write(content, 0, content.Length)
and use the three lines I posted:
Dim content() As Byte = My.Computer.FileSystem.ReadAllBytes(file)
response.ContentLength64 = content.Length
response.OutputStream.Write(content, 0, content.Length)
Do you really not understand what this code do?

As for reading chunks from the stream it has it uses, but first thing first.
 
I do understand what those 3 lines of code do and they work well, it's just that for some reason my <img src="test.jpg"> comes up as a broken link, that's what I don't understand.

I guess i'm wrong in thinking that it's because the bytes from the image aren't being written on the outputstream.
 
This is the next error you made:
file = "/index.html"
For each request you get your code ignores it and instead return index.html. You should take some time trying to understand what the code does, all of it. Really.
 
Back
Top