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

Posted

技术标签:

【中文标题】C# 如何通过 TCP 为 HTTP 发送文件?【英文标题】:C# How do you send a file via TCP for HTTP? 【发布时间】:2019-10-01 13:49:00 【问题描述】:

我目前面临的问题是,我无法让我的 C# 程序编写我想在响应中发送的文件(我正在编写文件的字节)并且有一个有效的 HTTP 响应,如果我已将文件附加到响应中,我正在测试它的浏览器会说 ERR_INVALID_HTTP_RESPONSE

最初我使用的是 HttpListener,但这要求我每次都以管理员身份运行我的 IDE,所以我决定放弃它并开始使用 TcpListener

这只是一个完全使用 C# 运行并使用来自 System.NetTcpListener 的简单 Web 服务器。到目前为止,我已经尝试使用StreamWriter 中的BaseStream 将文件的字节写入响应中。

我一直在四处寻找通过 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 链接中看到的一样,与我用来显示当前结果的屏幕截图的格式基本相同,即预期结果。

【问题讨论】:

404 OK?!?!好像有点不对劲。 可能是这样,但是当我测试尝试打开一个不存在的文件时它工作得很好 好吧,浏览器只看404部分; OK 更适合人类。但从技术上讲,404 应该是 Not Found 您从 HTTP 侦听器切换到 TCP 侦听器的“因为它需要管理员权限”的原因不足以实现您自己的网络服务器。除非您想花几天时间实现 http 标准请求和响应,否则最好坚持使用 http 侦听器。更容易解决的是管理员权限和 http 监听器的问题:***.com/questions/4019466/httplistener-access-denied 这取决于@Harry 的意见。我实际上只需要一个功能,它不会花费我几天的时间来实现标准的请求和响应,因为它们根本不需要我使用它。 【参考方案1】:

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 很高兴为您提供帮助。我添加了一个关于使用sw.Write 而不是sw.WriteLine 的智慧的简短段落 @AlexJBallz 您还需要非常小心地在交易的初始/标头部分中坚持使用 ASCII。 感谢您的帮助,我现在已经达到了我想要的结果:)

以上是关于C# 如何通过 TCP 为 HTTP 发送文件?的主要内容,如果未能解决你的问题,请参考以下文章

C# Tcp协议收发数据(TCPClient发,Socket收)

c#编程,通过向串口发数据的方式发送中文短信时,但中文显示乱码,如何软件解码?

udp 能跨网段广播 谁能告诉我udp跨网段怎么发消息,比如192.168.2.1到192.168.13.2去 c#的

如何通过 HTTP 使用 Java(或 C#)中的摘要身份验证 HTTP 发送 SOAP 请求?

OpenStack?HTTP协议

c#代码怎么通过outlook发邮件