Libcurl for a free open source, the client URL transfer Library, this article mainly analyzes the use of the process encountered in the card death problem.
Problem description
Libcurl use blocking method for HTTP download, curl_easy_perform execution, the program will be blocked here waiting for the download to end (success or failure), at this time, if the download a period after a network anomaly, Curl_easy_perform will not return to failure, The entire thread blocked the card to death.
Problem analysis
Replication: Connect the wireless network, and then perform curl_easy_perform download, the download process, disconnect the wireless network, Curl_easy_perform card dead, blocking the entire thread.
Cause: When disconnecting from a wireless network, use the command line netstat ano | findstr ' Connect IP ', you can find that Libcurl HTTP connection is not disconnected (do not know is not a Windows system bug), if the curlopt_timeout set to infinite Wait, curl_easy_ Perform will block the thread all the time.
Solution
1, if we do not set the curlopt_timeout to infinite Wait, is not the problem above, Curl_easy_perform will be in execution for some time (by the Curlopt_timeour set), end and return failure, But setting the right curlopt_timeout is a problem.
1
Curl_easy_setopt (Curl, curlopt_timeout, 0); Blocking forever, cannot find a suitable value
2, use the multi mode to download, and do not use easy mode, the only advantage of this method is that multi does not block, but immediately return. But the disadvantage is that the problem is caused by the need to block themselves, when we need to return to return, the second need to start a thread, you need to control the pace of the entire process.
3, in the download, another thread, if you find the download status card dead (can be achieved by periodically checking the file size to achieve), then interrupt the download thread from the outside. This method requires a separate thread, and it can cause instability to the entire program by being disconnected directly.
4, set the curlopt_timeout to 30s, to 30s for the partition point to continue transmission.
5, the use of Curlopt_low_speed_limit, Curlopt_low_speed_time
res = curl_easy_setopt (curl, Curlopt_low_speed_limit, 1024L);
res = curl_easy_setopt (curl, Curlopt_low_speed_time, 30L);
6, use Curlopt_progressfunction to set the schedule callback function, you can check the callback function inside the error, if there is interruption Curl_easy_perform, return download error.
#include <curl/curl.h>
int Progress_callback (void *clientp, double dltotal, double Dlnow, double ultotal, double ulnow);
Curlcode curl_easy_setopt (Curl *handle, curlopt_progressfunction, Progress_callback);