我正在尝试在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 文本,或者要求我保存它。
当客户端请求流媒体时,由于上述原因客户端无法播放视频。那么我现在应该做什么呢?感谢您阅读我的问题。请帮帮我。 :)
I am trying to write a proxy server in C language under Linux. It was working fine (I had the perception that it was working fine) until I tried it for streaming media.
Lemme first tell the problem and then I'll jump onto streaming media.
To read the incoming data from the website and forward it to the actual client I do this
count = read(websitefd,buffer,BUFSIZ);
write(clientfd,buffer,count);`
in a continuous while loop until I read up all the data on that socket.
Now the problem is if the actual website sends an HTTP packet with content length field as 1025 bytes and other part of data in other packets then still I always wait for BUFSIZ(8192 bytes) and then I send 8192 bytes to the client machine all together. for normal octet-stream
it works fine even though I know its not the right method, because I should forward the packets same as the actual server. So if actual server sends me 2 packet of sizes 1024 and 1024 bytes I send the client a packet of 2048 bytes with the first packet with the HTTP header saying that the content length is 900 bytes (rest all being the http header assuming) but actually I forward a packet of 2048 bytes to client. For Content Type: application/octet-stream it just downloads the whole thing and displays it either as image or html text or asks me to save it.
When the client request for a streaming media, because of the above reason the client is not able to play the video. So what should I do now ? Thanks for reading my question. Please help me out. :)
发布评论
评论(2)
首先,我强烈建议使用现有的代理服务器作为任何代理系统的基础。 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 错误。否则就继续传递数据,直到服务器关闭连接。我故意让这有点夸张 - 如果您从头开始实现代理服务器,则必须阅读该标准,否则肯定会引入浏览器不兼容和/或安全漏洞!所以请不要这样做。使用 lighttpd 或 varnish 或其他东西作为核心代理服务器,只需为您需要的任何功能编写一个插件即可。
First, I strongly recommend using an existing proxy server as the base of any proxy system. The HTTP standard is quite complex, much more than you realize. If you are going to implement a proxy server, read RFC 2616 at least three times first.
Second, your proxy server must parse HTTP headers to figure out how much it must send. The three main ways to know how much data to send are as follows:
Content-Length
header is present and noTransfer-Encoding
header is present: TheContent-Length
header specifies how much data to relay in bytes. Just go into a loop copying.Transfer-Encoding: chunked
header is present: You must parse the chunked transfer encoding chunk headers. This encoding is frequently used for streaming data, where the total size is not known ahead of time. It's also often used for dynamic data generated by scripts.Transfer-Encoding
header is present: Close the connection and report a 500 error, unless you know what that encoding is.Content-Length
header is not present, and noTransfer-Encoding
header is present: Check forConnection: close
(must be present, in HTTP/1.1) andConnection: keep-alive
(must NOT be present in HTTP/1.0). If these conditions are violated, trigger a 500 error. Otherwise just keep passing data until the server closes the connection.I'm deliberately making this a bit vauge - you MUST read the standard if you're implementing a proxy server from scratch, or you will certainly introduce browser incompatibilities and/or security holes! So please, don't do so. Use lighttpd or varnish or something as the core proxy server, and just write a plugin for whatever functionality you need.
我认为媒体是以块的形式传输的,即不存在内容长度并且数据被发送直到完成。
正如 bdonlan 所说,请阅读分块数据的工作原理,
我同意 HTTP 相当令人讨厌(由于许多变化和解释)
I suppose media is transferred in chunks, i.e no Content-Length is present and data is sent until finished.
As bdonlan said please read how chunked data works,
And i agree HTTP is pretty nasty (due to many changes and interpretations in time)