0

我正在尝试在 Linux 下用 C 语言编写代理服务器。在我尝试将它用于流媒体之前,它运行良好(我认为它运行良好)。

让我先说问题,然后我会跳到流媒体上。要从网站读取传入数据并将其转发给实际客户端,我会这样做

count = read(websitefd,buffer,BUFSIZ);

write(clientfd,buffer,count);` 

在一个连续的 while 循环中,直到我读取了该套接字上的所有数据。

现在的问题是,如果实际网站发送内容长度字段为 1025 字节的 HTTP 数据包和其他数据包中的其他部分数据,那么我仍然总是等待 BUFSIZ(8192 字节),然后我将 8192 字节一起发送到客户端机器. 正常情况octet-stream下,即使我知道它不是正确的方法,它也可以正常工作,因为我应该转发与实际服务器相同的数据包。因此,如果实际服务器向我发送 2 个大小为 1024 和 1024 字节的数据包,我会向客户端发送一个 2048 字节的数据包,第一个数据包的 HTTP 标头说内容长度为 900 字节(假设全部是 HTTP 标头)但实际上我将一个 2048 字节的数据包转发给客户端。对于内容类型:application/octet-stream 它只是下载整个内容并将其显示为图像或 html 文本或要求我保存它。

当客户端请求流媒体时,由于上述原因客户端无法播放视频。那我现在该怎么办?感谢您阅读我的问题。请帮帮我。:)

4

2 回答 2

3

首先,我强烈建议使用现有的代理服务器作为任何代理系统的基础。HTTP 标准非常复杂,比您意识到的要复杂得多。如果要实现代理服务器,请先阅读RFC 2616至少三遍。

其次,您的代理服务器必须解析 HTTP 标头以确定它必须发送多少。了解要发送多少数据的三种主要方法如下:

  • 如果存在Content-Length标头但不存在Transfer-Encoding标头:Content-Length标头指定要中继的数据量(以字节为单位)。只需进入循环复制。
  • 如果存在Transfer-Encoding: chunked标头:您必须解析分块传输编码块标头。这种编码经常用于流数据,其中总大小事先不知道。它也经常用于脚本生成的动态数据。
  • 如果存在其他Transfer-Encoding标头:关闭连接并报告 500 错误,除非您知道该编码是什么。
  • 如果Content-Length不存在标头,并且不存在Transfer-Encoding标头:检查Connection: close(必须存在,在 HTTP/1.1 中)和Connection: keep-alive(不得存在于 HTTP/1.0 中)。如果违反这些条件,则触发 500 错误。否则,只需继续传递数据,直到服务器关闭连接。

我故意让这有点模糊——如果你从头开始实现代理服务器,你必须阅读标准,否则你肯定会引入浏览器不兼容和/或安全漏洞!所以请不要这样做。使用lighttpdvarnish或其他东西作为核心代理服务器,只需为您需要的任何功能编写一个插件。

于 2011-02-25T15:59:07.790 回答
1

我想媒体是以块的形式传输的,即没有 Content-Length 存在,并且数据一直发送到完成。正如 bdonlan 所说,请阅读分块数据的工作原理,

而且我同意 HTTP 非常讨厌(由于时间上的许多变化和解释)

于 2011-02-25T16:07:11.037 回答