From af809923e4ca05215814b313f9b57f29b8ffdc33 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 23 Aug 2011 11:28:35 +0200 Subject: [PATCH] externalsocket.c: new example --- docs/examples/.gitignore | 1 + docs/examples/Makefile.inc | 2 +- docs/examples/externalsocket.c | 128 +++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 docs/examples/externalsocket.c diff --git a/docs/examples/.gitignore b/docs/examples/.gitignore index 7e5ecdb1d..42429d8f8 100644 --- a/docs/examples/.gitignore +++ b/docs/examples/.gitignore @@ -4,6 +4,7 @@ certinfo chkspeed cookie_interface debug +externalsocket fileupload fopen ftp-wildcard diff --git a/docs/examples/Makefile.inc b/docs/examples/Makefile.inc index c07520321..c6a3e9c5b 100644 --- a/docs/examples/Makefile.inc +++ b/docs/examples/Makefile.inc @@ -4,7 +4,7 @@ check_PROGRAMS = 10-at-a-time anyauthput cookie_interface debug fileupload \ https multi-app multi-debugcallback multi-double multi-post multi-single \ persistant post-callback postit2 sepheaders simple simplepost simplessl \ sendrecv httpcustomheader certinfo chkspeed ftpgetinfo ftp-wildcard \ - smtp-multi simplesmtp smtp-tls rtsp + smtp-multi simplesmtp smtp-tls rtsp externalsocket # These examples require external dependencies that may not be commonly # available on POSIX systems, so don't bother attempting to compile them here. diff --git a/docs/examples/externalsocket.c b/docs/examples/externalsocket.c new file mode 100644 index 000000000..39440afd5 --- /dev/null +++ b/docs/examples/externalsocket.c @@ -0,0 +1,128 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + * This is an example demonstrating how an application can pass in a custom + * socket to libcurl to use. This example also handles the connect itself. + */ +#include +#include +#include +#include + +#include +#include + +#include /* socket definitions */ +#include /* socket types */ +#include /* inet (3) funtions */ +#include /* misc. UNIX functions */ + +#include + +/* The IP address and port number to connect to */ +#define IPADDR "127.0.0.1" +#define PORTNUM 80 + +static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) +{ + int written = fwrite(ptr, size, nmemb, (FILE *)stream); + return written; +} + +static curl_socket_t opensocket(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address) +{ + curl_socket_t sockfd = *(curl_socket_t *)clientp; + /* the actual externally set socket is passed in via the OPENSOCKETDATA + option */ + return sockfd; +} + +static int sockopt_callback(void *clientp, curl_socket_t curlfd, + curlsocktype purpose) +{ + /* This return code was added in libcurl 7.21.5 */ + return CURL_SOCKOPT_ALREADY_CONNECTED; +} + +int main(void) +{ + CURL *curl; + CURLcode res; + struct sockaddr_in servaddr; /* socket address structure */ + curl_socket_t sockfd; + + curl = curl_easy_init(); + if(curl) { + /* + * Note that libcurl will internally think that you connect to the host + * and port that you specify in the URL option. + */ + curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999"); + + /* Create the socket "manually" */ + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { + fprintf(stderr, "ECHOCLNT: Error creating listening socket.\n"); + return 3; + } + + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(PORTNUM); + + if(inet_aton(IPADDR, &servaddr.sin_addr) <= 0 ) + return 2; + + if(connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) == + -1) { + close(sockfd); + printf("client error: connect: %s\n", strerror(errno)); + return 1; + } + + /* no progress meter please */ + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + + /* send all data to this function */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); + + /* call this function to get a socket */ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket); + curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd); + + /* call this function to set options for the socket */ + curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); + + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + + if(res) { + printf("libcurl error: %d\n", res); + return 4; + } + } + return 0; +}