C# 如何通过 TCP 发送 HTTP 文件?

7
我目前面临的问题是无法使我的C#程序将我想要发送的文件写入响应中(我正在写入文件的字节),并且拥有有效的HTTP响应,如果我将文件附加到响应中,则我测试它的浏览器会显示ERR_INVALID_HTTP_RESPONSE
最初,我使用的是HttpListener,但这要求我每次都以管理员身份运行我的IDE,因此我决定摆脱它,并开始使用TcpListener
这只是一个完全使用C#运行并利用System.Net中的TcpListener的简单Web服务器。到目前为止,我尝试使用StreamWriterBaseStream将文件的字节写入响应中。
我一直在寻找其他通过TCP / HTTP发送文件的方法,但似乎两件事很明显,即如何正确地执行此操作没有得到很好的记录,而且没有人针对此特定情况提出了同样的问题。
到目前为止,处理传入连接的响应代码如下。
      StreamReader sr = new StreamReader(client.GetStream());
      StreamWriter sw = new StreamWriter(client.GetStream());
      string request = sr.ReadLine();
      if (request != null) {
        //byte[] testData = Encoding.UTF8.GetBytes("Test");
        string[] tokens = request.Split(" ");
        try {
          FileInfo file = files[tokens[1]];
          byte[] fileBytes = File.ReadAllBytes(file.FullName);
          sw.WriteLine("HTTP/1.0 200 OK\n");
          sw.BaseStream.Write(fileBytes, 0, fileBytes.Length);
          sw.Flush();
        } catch {
          sw.WriteLine("HTTP/1.0 404 OK\n");
          sw.Write("<h1>Error 404</h1><p>The file you were looking for does not exist</p>");
          sw.Flush();
        }
      }
      client.Close();

预期的结果是浏览器将显示图像,就像您从imgur链接中看到的那样,基本上与我用来显示当前结果的截图相同的格式是预期的结果。

image taken from https://i.imgur.com/pxONnIP.png


5
「404 OK」?!?!这似乎有些不对劲。 - Kenneth K.
2
浏览器只看404部分;OK更多是为了人类。但从技术上讲,404应该是Not Found - Kenneth K.
那是个人观点,@Harry。我只需要一个函数,实现标准请求和响应并不需要花费我数天的时间,因为对于我使用它的目的来说,它们根本不必要。 - AlexJBallz
@AlexJBallz,我相信这是你第一次做这件事。只要你不自己编写客户端,而需要支持不同的客户端,比如标准浏览器,你将花费大量时间来支持所有意想不到的行为。 - Harry
@Harry 对于这个Web服务器的使用,那种支持是真的不必要的。 - AlexJBallz
显示剩余2条评论
1个回答

6

HTTP规定初始行和头部应以CRLF结尾(不是LF),双重CRLF应将初始行和头部与响应正文分开。

这是HTTP协议的超级便捷快速指南:

https://www.jmarshall.com/easy/http/

在从StreamWriter操作转换为基础流操作之前,您也可能需要刷新StreamWriter

sw.Write("HTTP/1.0 200 OK\r\n\r\n");
sw.Flush(); //  <-- HERE
sw.BaseStream.Write(fileBytes, 0, fileBytes.Length);

我建议避免使用WriteLine,因为不保证所有平台的行末标识符相同。


谢谢!已经有进展了,现在它可以下载文件而不是显示它,我应该能够从这里解决剩下的问题。 - AlexJBallz
1
@AlexJBallz 很高兴能帮忙。我添加了一个简短的段落,介绍了使用 sw.Write 而不是 sw.WriteLine 的智慧。 - spender
1
@AlexJBallz 在交易的初始/头部分,你还需要非常小心地坚持使用 ASCII。 - spender
感谢您的所有帮助,我现在已经达到了我想要的结果 :) - AlexJBallz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接