cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Couldn't Connect Error - Address already in use

From: Alfred Gebert <alfred.gebert_at_gmail.com>
Date: Tue, 6 Jul 2010 18:18:26 +0200

On Wed, Apr 28, 2010 at 11:04 PM, Daniel Stenberg <daniel_at_haxx.se> wrote:
> On Wed, 28 Apr 2010, Rahul R wrote:
>
>> I am frquently getting Couldn't connect error even though the server is
>> up. LibCurl debug logs show the error "Address already in use".
>>
>> I am using easy interface and new handle is used for every new
>> request.Only when i get redirect response i am reusing the same handle to
>> connect to the redirected host.
>
> Can you show us the source code for a complete little application that
> repeats this problem?
>

I have the same problem as Rahul.

I am using libcurl 7.19.4 on Windows XP and I want to call a
HTTP PUT operation around 8000 times. After about 4000 requests
curl_easy_perform() returns with error 7 (CURLE_COULDNT_CONNECT,
Couldn't Connect Error, Address already in use).

I modified the httpput.c example to reproduce the problem:
- Added a third program argument: how many time should the HTTP
  PUT be executed.
- If curl_easy_perform() does not return 0 then print an
  error and exit the program.
- Added a write callback which does nothing, because the loop
  must run fast. Without this modification I could not
  reproduce the error.
- Ported to Windows.

I run the program five times (third argument: 10000) with some
delay between the runs and got this output:

3931 request failed: 7
3929 request failed: 7
2 request failed: 7
1 request failed: 7
3937 request failed: 7

/*****************************************************************************
 * _ _ ____ _
 * Project ___| | | | _ \| |
 * / __| | | | |_) | |
 * | (__| |_| | _ <| |___
 * \___|\___/|_| \_\_____|
 *
 * $Id: httpput.c,v 1.11 2008-05-22 21:20:09 danf Exp $
 */

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>

#include <curl/curl.h>

/*
 * This example shows a HTTP PUT operation. PUTs a file given as a command
 * line argument to the URL also given on the command line.
 *
 * This example also uses its own read callback.
 *
 * Here's an article on how to setup a PUT handler for Apache:
 * http://www.apacheweek.com/features/put
 */

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
  size_t retcode;

  /* in real-world cases, this would probably get this data differently
     as this fread() stuff is exactly what the library already would do
     by default internally */
  retcode = fread((FILE*)ptr, size, nmemb, (FILE*)stream);

/* fprintf(stderr, "*** We read %d bytes from file\n", retcode); */

  return retcode;
}

size_t write_callback( void* Buffer, size_t BufferSize, size_t
BufferCount, void* Stream)
{
        return( BufferSize * BufferCount);
}

int main(int argc, char **argv)
{
  CURL *curl;
  CURLcode res;
  FILE * hd_src ;
  int hd ;
  struct stat file_info;

  char *file;
  char *url;

  if(argc < 4)
    return 1;

  file= argv[1];
  url = argv[2];
  int count = atoi(argv[3]);

  /* get the file size of the local file */
  hd = _open(file, _O_RDONLY) ;
  fstat(hd, &file_info);
  _close(hd) ;

  /* get a FILE * of the same file, could also be made with
     fdopen() from the previous descriptor, but hey this is just
     an example! */
  hd_src = fopen(file, "rb");

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  for( int i=0; i < count; i++)
  {
          fseek(hd_src, 0, SEEK_SET);

          /* get a curl handle */
          curl = curl_easy_init();
          if(curl) {
                  /* we want to use our own read function */
                  curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
                
                  /* enable uploading */
                  curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
                
                  /* HTTP PUT please */
                  curl_easy_setopt(curl, CURLOPT_PUT, 1L);
                
                  /* specify target URL, and note that this URL should include a file
       name, not only a directory */
                  curl_easy_setopt(curl, CURLOPT_URL, url);
                
                  /* now specify which file to upload */
                  curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);

                  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
                
                  /* provide the size of the upload, we specicially typecast the value
       to curl_off_t since we must be sure to use the correct data size */
                  curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                                                   (curl_off_t)file_info.st_size);
                
                  /* Now run off and do what you've been told! */
                  res = curl_easy_perform(curl);
                
                  if( res != 0)
                  {
                          printf( "%d request failed: %d\n", i+1, res);
                          exit( -1);
                  }
                
                  /* always cleanup */
                  curl_easy_cleanup(curl);
          }
  }

  fclose(hd_src); /* close the local file */

  curl_global_cleanup();
  return 0;
}

Alfred
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2010-07-06