C# c语言中的超小型web服务器#

C# c语言中的超小型web服务器#,c#,http,http-headers,C#,Http,Http Headers,我正在为教育目的编写一个超小型web服务器 对于以下代码,如果我请求包含图像的html页面,我将无法在浏览器中看到该图像。我做错了什么 static void Main(string[] args) { TcpListener listener = new TcpListener(9999); listener.Start(); while (true) { TcpClient client = listener.AcceptTcpClient(

我正在为教育目的编写一个超小型web服务器

对于以下代码,如果我请求包含图像的html页面,我将无法在浏览器中看到该图像。我做错了什么

static void Main(string[] args)
{
    TcpListener listener = new TcpListener(9999);
    listener.Start();
    while (true)
    { 
        TcpClient client = listener.AcceptTcpClient();
        string request = GetRequest(client.GetStream(),
            client.ReceiveBufferSize);
        WriteOutput(request, client.GetStream());
        client.Close();
    }
}

static void WriteOutput(string request, NetworkStream output)
{
    try
    {
        string[] reqs = request.Split(' ');
        WriteOutputHelper(output, reqs[1].Substring(1));
    }
    catch (Exception)
    {
        WriteOutputHelper(output, "404.html");
    }
}

private static void WriteOutputHelper(NetworkStream output, string file)
{
    byte[] statusLine = (new System.Text.ASCIIEncoding()).
        GetBytes(GetStatusLine(file) + "\r\n\r\n");
    output.Write(statusLine, 0, statusLine.Length);
    byte[] ContentType = 
        (new System.Text.ASCIIEncoding()).GetBytes(GetContentType(file) + 
            "\r\n\r\n");
    output.Write(ContentType, 0, ContentType.Length);
    byte[] response = System.IO.File.ReadAllBytes("C:\\" + file);
    output.Write(response, 0, response.Length);
    output.Flush();
}

static string GetContentType(string fileName)
{  
    string i = "<META http-equiv=\"Content-Type\" content=\"";
    if ((fileName.IndexOf(".htm") > -1) || (fileName.IndexOf(".html") > -1))
        i = i + "text/html";
    else if (fileName.IndexOf(".jpg") > -1)
        i = i + "image/jpeg";
    i = i + ";\">";
    return i;
}

static string GetStatusLine(string fileName)
{
    string i = "HTTP/1.0 ";
    if (fileName.IndexOf("404") > -1)
        return i + "404 Not Found";
    else if (fileName.IndexOf("jpg") > -1)
        return i + "302 Found";
    return i + "200 OK";
}

static string GetRequest(NetworkStream reqStream,int bufSize)
{
    byte[] bytesFrom = new byte[10025];
    reqStream.Read(bytesFrom, 0, bufSize);
    string request = System.Text.Encoding.ASCII.GetString(bytesFrom);
    return request;
}
对于上面的代码,我在fiddler中得到了这个错误

服务器未返回格式正确的HTTP头。HTTP头 应使用CRLFCRLF终止。这些以LFLF终止

我使用Unicode编码是因为我想将字符串转换为字节,而我只知道如何使用编码。

您是否考虑过使用cassini,它是开放源码的,项目名称为utildev。你完全可以自己写,但你永远无法涵盖所有的基础。对于问题所在的猜测是,LiteWeb服务器不支持所有mime类型

JPG的响应必须是HTTP头,然后是JPEG的内容,而不是它周围的任何HTML

差不多

HTTP/1.0 200 OK
Content-type: image/jpeg
Content-length: XXXXX

RAWJPEGDATA
将Jpeg中的字节数填入XXXXX,直接输出原始Jpeg数据,无需任何编码


使用Fiddler或Firebug帮助调试--它们显示发送的确切请求/响应。

看起来您正在发送jpeg文件的
302 Found
状态,用于重定向。您需要像对待HTML文件一样发送
200 OK

我认为问题出在
WriteOutputHelper
GetContentTypeHelper
方法中

标题不应该有
\r\n\r\n
,一个就足够了,而且GetContentTypeHelper方法应该返回如下标题:

Content-type: image/jpeg

不是用于(X)html内容的html
元素,不是HTTP头。

当您直接在浏览器的地址栏中请求jpg时,它是否工作?请显示正在生成的包含img标记的html。不,它只显示随机字符。这是页面的html Hello World,为什么要返回302以获取图像?这是一个重定向。请回答问题中新增的代码(imageTest方法)。我无法将代码粘贴到这里。只需像以前一样使用“\r\n\r\n”——您无法控制换行符是什么,HTTP需要它完全是“\r\n\r\n”,无论操作系统是什么。即使从System.Environment.Newline更改为“\r\n”@LouFranco,也没有运气。为什么要将换行符改为“\r\n\r\n”而不是“\r\n”?您需要额外的数据来限定标题的结束位置。它是HTTP规范的一部分。
Content-type: image/jpeg