我正在使用 curl 通过较差的连接下载 10MB 的文件。
如果下载中断,我将-C -
循环使用该选项来恢复下载(请参阅下面的代码片段)。
当我在本地测试并中断下载时,恢复功能有效 - 重新启动脚本后,它将恢复下载。
然而,在现场的一些物联网设备中,在传输过程中,curl 会发出类似的错误消息curl: (18) transfer closed with 2674439 bytes remaining to read
。
之后,下载恢复并完成 - 但文件已损坏。这种情况在不同设备上发生过多次,它们的共同点是它们在中国并且连接不良(curl 下载需要更长时间)。
鉴于 TCP 协议使用校验和来验证数据包,下载怎么可能损坏?我是不是漏掉了什么,也许我使用的选项与 curl 不兼容?
downloadFileResume() {
# $1 contains the URL to download
local fileName=$(basename "$1")
for (( i=0; i<=$numCurlRetries; i++ ))
do
# capture curl http code (-w %{http_code}) in stdout
curlHttpCode=$(curl -kSLf -u "$REPO_USERNAME:$REPO_PASSWORD" -w %{http_code} -O -C - "$1")
local res=$?
[ $res -eq 0 ] && return
# curl gives error when attempting to resume a completely downloaded file, it's a 416 error from the server
[ $curlHttpCode -eq 416 ] && echo "Error 416, assuming file is downloaded completely" && return
done
echo "failed to download $fileName"
return 1
}
非常感谢,米哈伊尔
答案1
卷曲错误 18当服务器承诺一定大小的内容但向客户端发送更多或更少的数据时,就会发生这种情况。例如,可能会发生这种情况:
- 服务器发送
Content-Length
标头和正文内容大小不匹配(可能是连接中断) - 服务器发送
Transfer-Encoding: chunked
但过早地结束了这一过程。
curl: (18) transfer closed with 2674439 bytes remaining to read
根据该错误消息,似乎是第一种情况。尝试使用--ignore-content-length
使用 cURL 命令行,或者使用下载管理器,例如wget
或者aria2
。