Annotation of embedaddon/curl/docs/examples/externalsocket.c, revision 1.1
1.1 ! misho 1: /***************************************************************************
! 2: * _ _ ____ _
! 3: * Project ___| | | | _ \| |
! 4: * / __| | | | |_) | |
! 5: * | (__| |_| | _ <| |___
! 6: * \___|\___/|_| \_\_____|
! 7: *
! 8: * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
! 9: *
! 10: * This software is licensed as described in the file COPYING, which
! 11: * you should have received as part of this distribution. The terms
! 12: * are also available at https://curl.haxx.se/docs/copyright.html.
! 13: *
! 14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
! 15: * copies of the Software, and permit persons to whom the Software is
! 16: * furnished to do so, under the terms of the COPYING file.
! 17: *
! 18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
! 19: * KIND, either express or implied.
! 20: *
! 21: ***************************************************************************/
! 22: /* <DESC>
! 23: * An example demonstrating how an application can pass in a custom
! 24: * socket to libcurl to use. This example also handles the connect itself.
! 25: * </DESC>
! 26: */
! 27: #include <stdio.h>
! 28: #include <string.h>
! 29: #include <stdlib.h>
! 30: #include <curl/curl.h>
! 31:
! 32: #ifdef WIN32
! 33: #include <windows.h>
! 34: #include <winsock2.h>
! 35: #include <ws2tcpip.h>
! 36: #define close closesocket
! 37: #else
! 38: #include <sys/types.h> /* socket types */
! 39: #include <sys/socket.h> /* socket definitions */
! 40: #include <netinet/in.h>
! 41: #include <arpa/inet.h> /* inet (3) functions */
! 42: #include <unistd.h> /* misc. Unix functions */
! 43: #endif
! 44:
! 45: #include <errno.h>
! 46:
! 47: /* The IP address and port number to connect to */
! 48: #define IPADDR "127.0.0.1"
! 49: #define PORTNUM 80
! 50:
! 51: #ifndef INADDR_NONE
! 52: #define INADDR_NONE 0xffffffff
! 53: #endif
! 54:
! 55: static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
! 56: {
! 57: size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
! 58: return written;
! 59: }
! 60:
! 61: static int closecb(void *clientp, curl_socket_t item)
! 62: {
! 63: (void)clientp;
! 64: printf("libcurl wants to close %d now\n", (int)item);
! 65: return 0;
! 66: }
! 67:
! 68: static curl_socket_t opensocket(void *clientp,
! 69: curlsocktype purpose,
! 70: struct curl_sockaddr *address)
! 71: {
! 72: curl_socket_t sockfd;
! 73: (void)purpose;
! 74: (void)address;
! 75: sockfd = *(curl_socket_t *)clientp;
! 76: /* the actual externally set socket is passed in via the OPENSOCKETDATA
! 77: option */
! 78: return sockfd;
! 79: }
! 80:
! 81: static int sockopt_callback(void *clientp, curl_socket_t curlfd,
! 82: curlsocktype purpose)
! 83: {
! 84: (void)clientp;
! 85: (void)curlfd;
! 86: (void)purpose;
! 87: /* This return code was added in libcurl 7.21.5 */
! 88: return CURL_SOCKOPT_ALREADY_CONNECTED;
! 89: }
! 90:
! 91: int main(void)
! 92: {
! 93: CURL *curl;
! 94: CURLcode res;
! 95: struct sockaddr_in servaddr; /* socket address structure */
! 96: curl_socket_t sockfd;
! 97:
! 98: #ifdef WIN32
! 99: WSADATA wsaData;
! 100: int initwsa = WSAStartup(MAKEWORD(2, 0), &wsaData);
! 101: if(initwsa != 0) {
! 102: printf("WSAStartup failed: %d\n", initwsa);
! 103: return 1;
! 104: }
! 105: #endif
! 106:
! 107: curl = curl_easy_init();
! 108: if(curl) {
! 109: /*
! 110: * Note that libcurl will internally think that you connect to the host
! 111: * and port that you specify in the URL option.
! 112: */
! 113: curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
! 114:
! 115: /* Create the socket "manually" */
! 116: sockfd = socket(AF_INET, SOCK_STREAM, 0);
! 117: if(sockfd == CURL_SOCKET_BAD) {
! 118: printf("Error creating listening socket.\n");
! 119: return 3;
! 120: }
! 121:
! 122: memset(&servaddr, 0, sizeof(servaddr));
! 123: servaddr.sin_family = AF_INET;
! 124: servaddr.sin_port = htons(PORTNUM);
! 125:
! 126: servaddr.sin_addr.s_addr = inet_addr(IPADDR);
! 127: if(INADDR_NONE == servaddr.sin_addr.s_addr) {
! 128: close(sockfd);
! 129: return 2;
! 130: }
! 131:
! 132: if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) ==
! 133: -1) {
! 134: close(sockfd);
! 135: printf("client error: connect: %s\n", strerror(errno));
! 136: return 1;
! 137: }
! 138:
! 139: /* no progress meter please */
! 140: curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
! 141:
! 142: /* send all data to this function */
! 143: curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
! 144:
! 145: /* call this function to get a socket */
! 146: curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
! 147: curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
! 148:
! 149: /* call this function to close sockets */
! 150: curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closecb);
! 151: curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd);
! 152:
! 153: /* call this function to set options for the socket */
! 154: curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
! 155:
! 156: curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
! 157:
! 158: res = curl_easy_perform(curl);
! 159:
! 160: curl_easy_cleanup(curl);
! 161:
! 162: close(sockfd);
! 163:
! 164: if(res) {
! 165: printf("libcurl error: %d\n", res);
! 166: return 4;
! 167: }
! 168: }
! 169:
! 170: #ifdef WIN32
! 171: WSACleanup();
! 172: #endif
! 173: return 0;
! 174: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>