简体   繁体   English

如何使用Indy TIdTCPClient实例从Web服务器(包括响应主体)检索完整的HTTP响应?

[英]How do I retrieve a complete HTTP response from a web server including response body using an Indy TIdTCPClient instance?

I have a Delphi 6 application that uses an Indy TIdTCPClient instance to communicate with a web server. 我有一个Delphi 6应用程序,它使用Indy TIdTCPClient实例与Web服务器通信。 The reason I am not using an HTTP client directly is because the the server is an image streaming server that uses the same socket connection for receiving the command to start streaming as it does to start "pushing" images back to you. 我之间没有直接使用HTTP客户端的原因是因为服务器是一个图像流服务器,它使用相同的套接字连接来接收命令以开始流式传输,就像它开始“推送”图像一样。 In other words, after you send it a typical HTTP POST request, it replies with an HTTP response, and immediately after that it starts sending out a stream of JPEG images. 换句话说,在您发送典型的HTTP POST请求后,它会回复HTTP响应,然后立即开始发送JPEG图像流。

I already know how to craft a proper POST request and send it using the TIdTCPClient WriteBuffer() method and then use the ReadBuffer() method to receive reply data. 我已经知道如何制作正确的POST请求并使用TIdTCPClient WriteBuffer()方法发送它,然后使用ReadBuffer()方法接收回复数据。 What I'd like to do instead is to send a POST request and then ask Indy to wait for a typical HTTP response including retrieving all the bytes in the response body if there is a Content-Length header variable. 我想要做的是发送一个POST请求,然后让Indy等待典型的HTTP响应,包括检索响应主体中的所有字节(如果有Content-Length头变量)。 I of course want it to leave the JPEG frames intact that may have piled in after the HTTP response in the receive queue until I start requesting them (that is, I don't want it including any of the JPEG frames in the HTTP response to my streaming request command until I ask for them using a successive read call). 我当然希望它保持JPEG帧完好无损,可能在接收队列中的HTTP响应之后堆积,直到我开始请求它们(也就是说,我不希望它包括HTTP响应中的任何JPEG帧)我的流请求命令,直到我使用连续的读取呼叫请求它们。

Is there a method that I can call on a TIdTCPClient that will retrieve completely a typical HTTP response with body content, and nothing else? 有没有一种方法可以在TIdTCPClient上调用,它将完全检索具有正文内容的典型HTTP响应,而不是其他内容? I thought about using SendCmd() and checking the LastCmdResult property (type: TIdRFCReply ) for the response, but I can't tell from the Indy documentation if it retrieves the response body content too if there is a Content-Length header variable as part of the response it returns, nor can I tell if it leaves the rest of the receive queue after the response intact. 我考虑过使用SendCmd()并检查LastCmdResult属性(类型: TIdRFCReply )作为响应,但是如果有一个Content-Length头部变量作为部分,我也无法从Indy文档中判断它是否也检索了响应主体内容它返回的响应,也不能告诉它在响应完好后是否离开接收队列的其余部分。

What is the best way to accomplish this mixed mode interaction with an HTTP web server that pushes out a stream of JPEG frames right after you make the HTTP request to start streaming? 完成与HTTP Web服务器的混合模式交互的最佳方法是什么,在您发出HTTP请求以开始流式传输之后立即推出JPEG帧流?

Also, if there is a clever way to have Indy split the frames using the JPEG frame WINBONDBOUDARY delimiting string, rather than accumulating blocks of data and parsing them out myself, please share that technique. 此外,如果有一个聪明的方法让Indy使用JPEG帧WINBONDBOUDARY分隔字符串分割帧,而不是累积数据块并自己解析它们,请分享该技术。

The correct way to read an HTTP response is to first read the CRLF-delimited response headers line-by-line until a blank line is encountered, aka a CRLF+CRLF sequence, then you can use those headers to decide how to read the remaining response data. 读取HTTP响应的正确方法是首先逐行读取CRLF分隔的响应标头,直到遇到空行,即CRLF + CRLF序列,然后您可以使用这些标头来决定如何读取剩余的响应数据。 The headers will tell you not only what kind of stream is being sent (via the Content-Type header), but also how the data is being framed ( Content-Length , Transfer-Encoding: chunked , something specific to the particular Content-Type , etc). 标题不仅会告诉您正在发送什么类型的流(通过Content-Type标头),还会告诉您数据的框架方式( Content-LengthTransfer-Encoding: chunked ,特定于特定Content-Type等)。

To receive the headers, you can use the connection's Capture() method, setting its ADelim parameter to a blank string. 要接收标头,可以使用连接的Capture()方法,将其ADelim参数设置为空字符串。

How you read the remaining data afterwards depends on the actual formatting/framing of the stream. 之后如何读取剩余数据取决于流的实际格式/框架。 Without knowing exactly what kind of stream you are receiving, there is no way to advise you how best to read it, as there are several different types of streaming protocols used by HTTP servers, and most of them are not standardized. 如果不确切知道您接收的是哪种流,则无法建议您如何最好地阅读它,因为HTTP服务器使用了几种不同类型的流协议,而且大多数都没有标准化。 Provide that information, then I/we can show you how to implement it with Indy. 提供该信息,然后我/我们可以向您展示如何使用Indy实现它。

You cannot use SendCmd() as the HTTP protocol does not format its responses in a way that is compatible with that method. 您不能使用SendCmd()因为HTTP协议不会以与该方法兼容的方式格式化其响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM