HTTP server, bilder/attachments

Permalänk
Medlem

HTTP server, bilder/attachments

Hej,

Jag försöker skriva en väldigt simpel http server, framför allt för att ha något kul projekt och för att lära mig nya saker. Jag har dock fastnat lite, säkerligen för att jag inte har läst tillräckligt mycket om hur protokollet fungerar - men jag frågar här ändå. Hittills har jag fått en enkel "hello world"-aktig index.html sida att visas i en browser efter att en browser skickat en GET begäran. Det fungerar även med attachments eller bilder, men det blir väldigt långsamt. Browsern verkar vänta på något som inte inträffar, det som händer är att en GET begäran skickas till min server, servern skickar filen på någon millisekund, men filhämtaren eller "spara som menyn" dyker inte upp förrän flera sekunder senare. Därför känns det som jag har missat något uppenbart som borde göras.

Förklarar lite kort hur jag har gjort nu. Jag skickar en GET begäran från firefox, inget konstigt, där jag ber om, t.ex "bild.jpg", servern svarar då med följande header:

Status: HTTP/1.1 200 OK Content-Length: <storlek på filen> Content-Type: image/jpeg Server: <något> Accept-Ranges: bytes Connection: close

Sedan läses filen in med en Filestream (det är faktiskt redan gjort innan för att försäkra mig om att det inte var det som tog tid) och filen skickas i ett antal delar (har testat olika stora delar här, ingen skillnad). Sedan stänger servern sin socket. Sen står browsern och "väntar på <url>" i ett antal sekunder innan den visar/börjar hämta bilden, eller innan "spara som menyn" dyker upp. Det känns som om browsern väntar på något här, som inte händer utan istället blir det någon form av timeout.

Någon som har någon idé om vad jag missar? Kanske något jag missat i headern?

Permalänk
Medlem

Har du dubbel "\n\r" i slutet av hela headern?

Permalänk
Medlem
Skrivet av iXam:

Har du dubbel "\n\r" i slutet av hela headern?

Ja, det har jag.

Bara för att testa skrev jag samma program med hjälp av den färdiga klassen HttpListener (C#). Nu använde jag inte det från början eftersom att målet var att lära mig, men jag kan ju nämna att jag hade samma problem där. Iofs så skickar jag ju bilden precis likadant i båda tillfällena, och man skapar ju fortfarande headern själv, så det utesluter ju kanske inte så mycket.

EDIT:

Har testat lite till nu, jag vet inte hur jag gjorde det här innan utan att upptäcka det, men jag har nu kommit fram till att det som tar tid är faktiskt att skicka filen. Men då undrar jag ju förstås varför det tar ungefär 2 sekunder att skicka en fil på 42kb över ett 100/100 nät? Här är koden för att skicka själva filen, inget konstigt enligt mig.

int i = 0; while (bytesSent < fs.Length) { int bytesRead = fs.Read(buffer, 0, ((buffer.Length < fs.Length) ? buffer.Length : (int)fs.Length - bytesSent)); _context.Response.OutputStream.Write(buffer, 0, bytesRead); bytesSent += bytesRead; Console.WriteLine("Part of file sent:" + i); i++; }

Filen jag skickar är en fil på 42kb och buffern är 20kb stor så att filen delas upp i 3 delar. När den ska skicka filen så börjar det med en lång paus, sen skriver programmet i konsollen "Part of file sent:0", de två delarna efter det tar ingen tid alls (några millisekunder), men just den första delen tar mycket längre tid att skicka. Samma sak händer när jag använder sockets. Någon som har någon idé?

PS. En fråga till, lite vid sidan om, varför skickar firefox två GET requests för bild.jpg, där den andra för övrigt skickas instant, utan någon paus? Kan det ha något med det hela att göra?

Permalänk
Medlem

Installera firebug och kolla exakt vad FF skickar och vad den sen får tillbaka. Kan vara bra grejj för framtida buggar också.
Vad händer om du låter buffern vara lika stor som filen och du läser och skickar den i ett svep. Om det löser problemet så kan du säkert lösa hela altet.