cURL / Mailing Lists / curl-library / Single Mail

curl-library

Strange behaviour in multi interface

From: Alex Alex <alexone1980_at_yahoo.it>
Date: Wed, 1 Apr 2009 12:14:12 +0000 (GMT)

Hi all.

the below code is __absolutely identical___ to multi-double.c, except for the for(;;) loop and the following two lines, at the end of each cycle:

> curl_multi_remove_handle(multi_handle, http_handle);
> curl_multi_remove_handle(multi_handle, http_handle2);

Now: if both connections are OK, i can continously "grab" http pages (they are video frames, in my case) from the two urls.
Unfortunately, If one of the connection becomes idle, meanwhile, for an unknown reason select() blocks for the used timeout at each cycle.
Therefore, the other transfer becomes slower, even if its connection is OK and it can give me data.

What can be the cause ?
Is there a way to solve that? Or, at least, a work-around ?

Many thanks to all

Alex

/*****************************************************************************
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * $Id: multi-double.c,v 1.4 2006/10/13 14:01:19 bagder Exp $
 *
 * This is a very simple example using the multi interface.
 */

#include <stdio.h>
#include <string.h>

/* somewhat unix-specific */
#include <sys/time.h>
#include <unistd.h>

/* curl stuff */
#include <curl/curl.h>

/*
 * Simply download two HTTP files!
 */
int main(int argc, char **argv)
{
  CURL *http_handle;
  CURL *http_handle2;
  CURLM *multi_handle;

  int still_running; /* keep number of running handles */

  http_handle = curl_easy_init();
  http_handle2 = curl_easy_init();

  /* set options */
  //curl_easy_setopt(http_handle, CURLOPT_URL, "http://192.106.230.183/snap.jpg?JpegSize=S");
  curl_easy_setopt(http_handle2, CURLOPT_URL, "http://192.106.230.183/snap.jpg?JpegSize=S");
  /* set options */
  curl_easy_setopt(http_handle2, CURLOPT_URL, "http://192.106.230.78/axis-cgi/jpg/image.cgi");

  /* init a multi stack */
  multi_handle = curl_multi_init();
 
for(;;)
{
  /* add the individual transfers */
  curl_multi_add_handle(multi_handle, http_handle);
  curl_multi_add_handle(multi_handle, http_handle2);

  /* we start some action by calling perform right away */
  while(CURLM_CALL_MULTI_PERFORM ==
        curl_multi_perform(multi_handle, &still_running));

  while(still_running) {
    struct timeval timeout;
    int rc; /* select() return code */

    fd_set fdread;
    fd_set fdwrite;
    fd_set fdexcep;
    int maxfd;

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    /* set a suitable timeout to play around with */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    /* get file descriptors from the transfers */
    curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

    /* In a real-world program you OF COURSE check the return code of the
       function calls, *and* you make sure that maxfd is bigger than -1 so
       that the call to select() below makes sense! */

    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch(rc) {
    case -1:
      /* select error */
      break;
    case 0:
      printf("timeout\n");
    default:
      /* timeout or readable/writable sockets */
      while(CURLM_CALL_MULTI_PERFORM ==
            curl_multi_perform(multi_handle, &still_running));
      break;
    }
  }

  curl_multi_remove_handle(multi_handle, http_handle);
  curl_multi_remove_handle(multi_handle, http_handle2);
}

  curl_multi_cleanup(multi_handle);
  curl_easy_cleanup(http_handle);
  curl_easy_cleanup(http_handle2);

  return 0;
}
Received on 2009-04-01