Creating web server software - unreliable, hangs up, strange browser behaviour - what is wrong?

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Hello again, fellow programmers :)
Ive come upon a few major, confusing glitches in my latest project, software for showing spesific hard-coded webpages to a browser. Say, there is a file in my project called "panel.htm", and is hosted in my application. When a browser calls for it on the applications listening port (in this case 8081), it will return the file to the browser.
The application has a number of files in its resources: favicon.ico, main.css, mainsc.js, panel.htm, pngicon2.png and refresh.png. (Please note that the file mainsc.js is referred to within panel.htm as main.js, but this has been taken care of to support in code.)
I can successfully make the application listen to port 8081, and when the browsers opens the document, after browser headers have been received, it will send headers back followed by the data. But this doesnt work. Ive come uponmany glitches as of yet:
  • When I load a page with an image loaded in an <img> tag, it does not load, but if said image is opened in a separate tag, it is loaded.
  • The main.css file is sometimes not served by the server, thereby breaking all layout on panel.htm. This seems to happen randomly.
  • All javascript from mainsc.js fails to execute.
  • Favicon.ico does not load from panel.htm even thought the browser requests it (can be seen from the console). However, if it is opened in a separate tab, itis loaded (as happens with the image files).
  • The server randomly hangs up in an infinite loop when receiving an infinite number of null characters from the client (browser), using a full CPU core. It is supposed to stop when it receives the bytes 0D-0A-0D-0A.
  • Tried a workaround for the above by having it look for 00-00-00-00 instead and trim away the null characters afterwards, but this causesall further code to fail, even writing a string to console fails. No error messages appear. The code lets itself be stepped through, but nothing happens.
I have absolutely no idea what causes all these bugs. I havent really read the HTTP documentation, but Ive looked at how Apache servers transfer data by having a client connect to it, send headers and await data. I then cloned its behaviour.
Heres my code so far:Imports System.Net.SocketsImports System.IOImports System.NetImports System.DrawingModule Module1 Sub Main() Dim tcpl As New TcpListener(IPAddress.Any, 8081) Do tcpl.Start() Dim tcpc As TcpClient = tcpl.AcceptTcpClient() Dim tcps As Stream = tcpc.GetStream() Dim bytesRecv As Integer = 0 Dim lastBytes As String = "FFFFFFFF"
Setting the following to 00000000 will cause ALL FOLLOWING
CODE TO STOP WORKING. The code can be successfully stepped
through, but e.g. if I come down to Console.WriteLine,
nothing actually ends up in the console... Dim stopBytes As String = "0D0A0D0A" Dim resHd As List(Of String) Dim recvData As String = "" Do Until lastBytes = stopBytes Dim bf(0) As Byte tcps.Read(bf, 0, 1) bytesRecv += 1 lastBytes = lastBytes.Substring(2) lastBytes &= Hex(bf(0)).PadLeft(2, "0"c) recvData &= Stringify(bf) Debug.Write(Hex(bf(0)).PadLeft(2, "0"c)) Loop Console.WriteLine(recvData) recvData = recvData.Trim({Chr(0)}) resHd = New List(Of String)(Split(recvData, vbNewLine)) Dim data() As Object = ReturnData(Split(resHd(0), " ")(1)) Dim responseHeaders() As String = { _ "HTTP/1.1 302 Found", _ "Date: " & Date.Now.ToString("R"), _ _ "Server: CraftShare/1.0.0", _ _ "X-Powered-By: CraftShare", _ "Keep-Alive: timeout=5, max=100", _ "Connection: Keep-Alive", _ "Content-Type: " & data(1), _ "", _ ""} Dim responseHeader As String = Join(responseHeaders, vbNewLine) Dim sendStr As String = responseHeader Dim sendData As New List(Of Byte)(System.Text.Encoding.ASCII.GetBytes(sendStr)) sendData.AddRange(data(0)) tcps.Write(sendData.ToArray(), 0, sendData.Count) tcps.Close() tcps.Dispose() tcpc.Close() tcpl.Stop() Loop End Sub Private Function ReturnData(urlreq) As Object() Select Case LCase(urlreq) Case "/favicon.ico" Dim ms As New MemoryStream() My.Resources.favicon.Save(ms) Dim bytedata() As Byte = ms.ToArray() ms.Close() ms.Dispose() Return {bytedata, "image/x-icon", LCase(urlreq)} Case "/main.css" Return {Bytify(My.Resources.main), "text/css", LCase(urlreq)} Case "/main.js" Return {Bytify(My.Resources.mainsc), "text/javascript", LCase(urlreq)} Case "/panel" Return {Bytify(My.Resources.panel), "text/html", LCase(urlreq)} Case "/pngicon2.png" Dim bytedata() As Byte = GetImageBytes(My.Resources.pngicon2, Imaging.ImageFormat.Png) Return {bytedata, "image/png", LCase(urlreq)} Case "/refresh.png" Dim bytedata() As Byte = GetImageBytes(My.Resources.refresh, Imaging.ImageFormat.Png) Return {bytedata, "image/png", LCase(urlreq)} Case Else Return {Bytify("<html><head><link rel=""shortcut icon" "./pngicon2.png" </head><body><h1>404 Not Found</h1></body></html>"), "text/html", LCase(urlreq)} End Select End Function Private Function Stringify(data() As Byte) As String Return System.Text.Encoding.ASCII.GetString(data) End Function Private Function Bytify(str As String) As Byte() Return System.Text.Encoding.ASCII.GetBytes(str) End Function Private Function GetImageBytes(img As Bitmap, format As Imaging.ImageFormat) As Byte() Dim ms As New MemoryStream() img.Save(ms, System.Drawing.Imaging.ImageFormat.Png) Dim bytedata() As Byte = ms.ToArray() ms.Close() ms.Dispose() Return bytedata End FunctionEnd Module
Any feedback will be highly appreciated. Thanks for taking the time to look at my problem.
Sincerely yours,
- bilde2910
If a post is helpful to you or solves a problem, remember to mark it as answer, propose it as answer or vote up.
Check out my development so far!

View the full article
 
Back
Top