Prerequisites Overview
When you need to work with multiple URLs at the same time, you can do this in Curl_multi_perform mode, as in code 1:
1 //Initializes a multi Curl object2CURLM * Curl_m =Curl_multi_init ();3CURL *my_curl[curl_num];4 Charrcvbuf[curl_num][maxheadlen] = {0 };5 //other initialization code skipped ...6 7 //Execute multiple URLs8 while(running_handles)9 {Ten if(-1==Curl_multi_select (curl_m)) one { aprintf"Curl_multi_select error!\n"); - break; - } the Else { - //Select Supervisor hears the event and calls Curl_multi_perform to notify Curl to perform the appropriate action// - while(curlm_call_multi_perform = = Curl_multi_perform (curl_m, &running_handles)); - } + } - + //parsing Data a intmsgs_left; atCurlmsg *curl_msg; - while(curl_msg = Curl_multi_info_read (curl_m, &Msgs_left ))) - { - if(curlmsg_done = = curl_msg->Msg) - { - intidx; in for(idx =0; IDX < curl_num; ++idx) - { to if(curl_msg->easy_handle = = My_curl[idx]) break; + } - the if(idx = =Curl_num) * { $printf"Curl not found!\n" );Panax Notoginseng } - Else the { +printf"\ncurl[%d] rcvbuf:\n%s\n", idx,rcvbuf[idx]); a //Data Processing ... the } + } -}
Summary of issues
Now my URL is a subscription, each curl will always receive data (even if no data will be received every 10s a frame heartbeat message), never quit, that is, the above loop is always executing, so I can not run to the "parse data" step . So I need to determine in the loop if a curl has new data coming in .
Method 1 (no)
The first thought is to directly move the Curl_multi_info_read () function directly into the loop to see if the data can be received, as in code 2:
1 //executes multiple URLs and parses the data2 while(running_handles)3 {4 if(-1==Curl_multi_select (curl_m))5 {6printf"Curl_multi_select error!\n");7 break;8 }9 Else {Ten //Select Supervisor hears the event and calls Curl_multi_perform to notify Curl to perform the appropriate action// one while(curlm_call_multi_perform = = Curl_multi_perform (curl_m, &running_handles)); a //detect which curl[idx] came from the data - while(curl_msg = Curl_multi_info_read (curl_m, &Msgs_left ))) - { the if(curlmsg_done = = curl_msg->Msg) - { - intidx; - for(idx =0; IDX < curl_num; ++idx) + { - if(curl_msg->easy_handle = = My_curl[idx]) break; + } a if(idx = =Curl_num) at { -printf"Curl not found!\n" ); - } - Else - { -printf"\ncurl[%d] rcvbuf:\n%s\n", idx,rcvbuf[idx]); in //Data Processing ... -Memset (rcvbuf[idx],0,sizeof(rcvbuf[idx]));//empty the BUF cycle and use it . to } + } - } the } *}
Obviously I think a lot more, so the only difference after this processing is, which curl is finished to print which data (code 1 is only waiting to wait until all of the curl is finished to exit the loop and then print rcvbuf[idx]), but my curl is subscribed, do not finish at all, so I can not print , unless rcvbuf[idx] overflows ...
Method 2 (not Yet)
rcvbuf[idx] overflow? This is certainly not possible, but reminds me of the curl_easy_setopt () function , which can configure the various functions of curl , perhaps there is always one to satisfy me:
Curlopt_timeout_ms Configuration time-out?
no, This is going to time Out. Curl hangs directly;
Curlopt_range Configure a breakpoint to continue to pass?
Seems to be able to, through the test found that the specified xx bytes full after the curl will quit, even if there is data behind him also don't, this is not what we want to See.
Is there a configuration to receive the timeout time?
ditto, more than the number of s after even if there is data he did not, Nor.
...
Believe that through the configuration of the curl_easy_setopt () function should be the most official practice, but the younger brother did not find relevant articles, their own research has not come out, waiting for expert guidance.
Method 3 (feasible, Defective)
helpless, suddenly thought that since curl[idx] received data in rcvbuf[idx], why not directly check rcvbuf[idx] there is no data , the following code 3:
1 //executes multiple URLs and parses the data2 while(running_handles)3 {4 if(-1==Curl_multi_select (curl_m))5 {6printf"Curl_multi_select error!\n");7 break;8 }9 Else {Ten //Select Supervisor hears the event and calls Curl_multi_perform to notify Curl to perform the appropriate action// one while(curlm_call_multi_perform = = Curl_multi_perform (curl_m, &running_handles)); a //detect which curl[idx] came from the data - intIDX =0; - for(idx =0; IDX < curl_num; ++idx) the { - if(rcvbuf[idx][0] = = NULL)//curl[idx] did not receive Data. - Continue; -printf"curl[%d] rcvbuf:\n%s\n", idx, rcvbuf[idx]); + //Data Processing ... -Memset (rcvbuf[idx],0,sizeof(rcvbuf[idx])); + } a } at}
The above process does satisfy the requirements, but the method is a bit clumsy and there are 2 obvious flaws:
1. Check all curl once every time, low efficiency;
2. Once a curl dies for some reason, how can I tell which Curl is hanging?
So is there an official way to deal with this problem? Still need to answer, keep attention to Update.
Libcurl using the Curl_multi_perform () function to perform a subscription type URL problem