Delphi - 使用套接字从 Web 下载文件
Posted
技术标签:
【中文标题】Delphi - 使用套接字从 Web 下载文件【英文标题】:Delphi- downloading files from the web with sockets 【发布时间】:2013-02-08 22:58:32 【问题描述】:我尝试过 Synapse、Indy 和 ICS,但我对它们不满意。我想同时下载多个部分的多个文件,支持恢复、gzip 编码的文件、cookie、使用 POST 登录网站等。所以我想我会用套接字写。 但我看到 Delphi 中有很多可用的套接字:TTcpClient、TRawSocket、TCGIRequest、TClientSocket 等等。它们都没有完整的文档记录——很难找到使用示例。我尝试使用 TTcpClient 但有时程序会冻结然后超时,我不知道为什么。等待回复时似乎有问题。这肯定不是服务器问题,因为我在 localhost 上进行了测试。 用于 HTTP 协议的最佳套接字是什么?好用吗?
我想在 Delphi 7 和 XE2 中都使用。我不想使用 WinAPI 之类的任何东西,所以我不必处理 PChars 和其他非 Delphi 的东西。
我正在考虑类似的东西:
1) 完全符合我的要求 - 在同一个文件中下载多个带有多个文件进度条的片段
或
2) 类似 telnet- 所以我只是将 HTTP 命令编写为字符串,然后我得到字节数组作为回报,我可以将其转换为字符串或保存到 tstreams 中。
【问题讨论】:
试试 WinInet。 Delphi 完全支持它;它不需要任何附加组件。它可能非常适合您的目的:cryer.co.uk/brian/delphi/wininet.htm 印地有什么问题?还是异步 ICS(可能更适合并行文件下载)? 更进一步,您使用的是什么版本的 Delphi?TClientSocket
现在已经过时了,即使在旧版本的 Delphi 中支持,仍然强烈建议不要考虑使用它们。 Delphi 版本对于这样的问题很重要。更不用说这首先对 *** 来说不是一个合适的问题。
“我应该使用什么”对于 S/O 来说是一个糟糕的问题,“易于使用的东西”更糟糕,它是主观的。两者结合在一起是一个可怕的问题。
@Tom:TIdHTTP 支持你所要求的一切,你只需要知道如何使用它。详情见我的回答。
【参考方案1】:
我无法评论其他库,但 Indy 支持您所要求的一切。
如果服务器支持,TIdHTTP
组件可以使用字节范围下载文件。您可以使用TIdHTTP.Head()
方法检查服务器是否返回给定URL 的Accept-Ranges: bytes
标头。如果是这样,那么您可以在从该 URL 下载数据时根据需要将 TIdHTTP.Request.ContentRangeStart
和 TIdHTTP.Request.ContentRangeEnd
属性设置为所需的字节偏移量。要同时下载资源的多个部分,只需并行运行多个线程,每个线程都有自己的TIdHTTP
组件。然后,您必须下载多个片段以分隔临时文件,然后在完成后将它们合并到最终文件中,或者创建一个预先确定大小的文件,然后在所需的起始偏移量处打开多个 TFileStream
对象TIdHTTP
写信给。
TIdHTTP
支持 cookie。您可以将TIdCookieManager
组件分配给TIdHTTP.CookieManager
属性,或者您可以不分配它,TIdHTTP
将在内部创建一个TIdCookieManager
对象。无论哪种方式,还要将 TIdHTTP.AllowCookies
属性设置为 True。
根据服务器是使用基于 HTTP 的身份验证还是基于 WebForm 的身份验证,可以使用两种不同的方式之一来完成网站登录:
-
1234563然后根据需要设置
TIdHTTP.Request.UserName
和TIdHTTP.Request.Password
属性。如果 WebServer 在请求期间要求进行身份验证,TIdHTTP
将选择适当的类并使用它使用指定的凭据登录。如果服务器拒绝凭据,TIdHTTP.OnAuthorization
事件将被触发,让您有机会更改凭据并重试。
对于 WebForm 身份验证,有一个 TIdMultipartFormDataStream
类可以传递给 TIdHTTP.Post()
方法,用于发布 multipart/form-data
格式的 POST 请求。
Indy 10 中的TIdHTTP
支持 gzip 文件和 deflate 压缩文件(Iny 9 和更早版本中的TIdHTTP
不支持压缩)。您可以将TIdZLibCompressorBase
派生组件(例如TIdCompressorZLib
)分配给TIdHTTP.Compressor
属性,TIdHTTP
将为您处理所有细节,包括发送适当的Accept-Encoding
请求标头,并检查服务器的Transfer-Encoding
响应头。
TIdHTTP
具有OnWorkBegin
、OnWork
和OnWorkEnd
事件,可用于进度条等。 OnWorkBegin
事件有一个 AWorkCountMax
参数,它指定传输的字节总数(如果已知),否则将为 0(使用 Content-Length
标头的 HTTP 响应将相应地设置 AWorkCountMax
,但 HTTP 响应不会使用 Transfer-Encoding: chunked
标头)。 OnWork
事件有一个 AWorkCount
参数,它指定到目前为止已经传输了多少字节,而不管 AWorkCounMax
的值是多少。
【讨论】:
感谢您的回答和您的组件。由于我没有其他回复并且他们关闭了我的问题,我将再试一次 Indy :)以上是关于Delphi - 使用套接字从 Web 下载文件的主要内容,如果未能解决你的问题,请参考以下文章