chkspeed.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2022, Daniel Stenberg, <[email protected]>, 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.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. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. /* <DESC>
  25. * Show transfer timing info after download completes.
  26. * </DESC>
  27. */
  28. /* Example source code to show how the callback function can be used to
  29. * download data into a chunk of memory instead of storing it in a file.
  30. * After successful download we use curl_easy_getinfo() calls to get the
  31. * amount of downloaded bytes, the time used for the whole download, and
  32. * the average download speed.
  33. * On Linux you can create the download test files with:
  34. * dd if=/dev/urandom of=file_1M.bin bs=1M count=1
  35. *
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <time.h>
  41. #include <curl/curl.h>
  42. #define URL_BASE "http://speedtest.your.domain/"
  43. #define URL_1M URL_BASE "file_1M.bin"
  44. #define URL_2M URL_BASE "file_2M.bin"
  45. #define URL_5M URL_BASE "file_5M.bin"
  46. #define URL_10M URL_BASE "file_10M.bin"
  47. #define URL_20M URL_BASE "file_20M.bin"
  48. #define URL_50M URL_BASE "file_50M.bin"
  49. #define URL_100M URL_BASE "file_100M.bin"
  50. #define CHKSPEED_VERSION "1.0"
  51. static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
  52. {
  53. /* we are not interested in the downloaded bytes itself,
  54. so we only return the size we would have saved ... */
  55. (void)ptr; /* unused */
  56. (void)data; /* unused */
  57. return (size_t)(size * nmemb);
  58. }
  59. int main(int argc, char *argv[])
  60. {
  61. CURL *curl_handle;
  62. CURLcode res;
  63. int prtall = 0, prtsep = 0, prttime = 0;
  64. const char *url = URL_1M;
  65. char *appname = argv[0];
  66. if(argc > 1) {
  67. /* parse input parameters */
  68. for(argc--, argv++; *argv; argc--, argv++) {
  69. if(strncasecmp(*argv, "-", 1) == 0) {
  70. if(strncasecmp(*argv, "-H", 2) == 0) {
  71. fprintf(stderr,
  72. "\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
  73. appname);
  74. exit(1);
  75. }
  76. else if(strncasecmp(*argv, "-V", 2) == 0) {
  77. fprintf(stderr, "\r%s %s - %s\n",
  78. appname, CHKSPEED_VERSION, curl_version());
  79. exit(1);
  80. }
  81. else if(strncasecmp(*argv, "-A", 2) == 0) {
  82. prtall = 1;
  83. }
  84. else if(strncasecmp(*argv, "-X", 2) == 0) {
  85. prtsep = 1;
  86. }
  87. else if(strncasecmp(*argv, "-T", 2) == 0) {
  88. prttime = 1;
  89. }
  90. else if(strncasecmp(*argv, "-M=", 3) == 0) {
  91. long m = strtol((*argv) + 3, NULL, 10);
  92. switch(m) {
  93. case 1:
  94. url = URL_1M;
  95. break;
  96. case 2:
  97. url = URL_2M;
  98. break;
  99. case 5:
  100. url = URL_5M;
  101. break;
  102. case 10:
  103. url = URL_10M;
  104. break;
  105. case 20:
  106. url = URL_20M;
  107. break;
  108. case 50:
  109. url = URL_50M;
  110. break;
  111. case 100:
  112. url = URL_100M;
  113. break;
  114. default:
  115. fprintf(stderr, "\r%s: invalid parameter %s\n",
  116. appname, *argv + 3);
  117. exit(1);
  118. }
  119. }
  120. else {
  121. fprintf(stderr, "\r%s: invalid or unknown option %s\n",
  122. appname, *argv);
  123. exit(1);
  124. }
  125. }
  126. else {
  127. url = *argv;
  128. }
  129. }
  130. }
  131. /* print separator line */
  132. if(prtsep) {
  133. printf("-------------------------------------------------\n");
  134. }
  135. /* print localtime */
  136. if(prttime) {
  137. time_t t = time(NULL);
  138. printf("Localtime: %s", ctime(&t));
  139. }
  140. /* init libcurl */
  141. curl_global_init(CURL_GLOBAL_ALL);
  142. /* init the curl session */
  143. curl_handle = curl_easy_init();
  144. /* specify URL to get */
  145. curl_easy_setopt(curl_handle, CURLOPT_URL, url);
  146. /* send all data to this function */
  147. curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
  148. /* some servers do not like requests that are made without a user-agent
  149. field, so we provide one */
  150. curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
  151. "libcurl-speedchecker/" CHKSPEED_VERSION);
  152. /* get it! */
  153. res = curl_easy_perform(curl_handle);
  154. if(CURLE_OK == res) {
  155. curl_off_t val;
  156. /* check for bytes downloaded */
  157. res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD_T, &val);
  158. if((CURLE_OK == res) && (val>0))
  159. printf("Data downloaded: %lu bytes.\n", (unsigned long)val);
  160. /* check for total download time */
  161. res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME_T, &val);
  162. if((CURLE_OK == res) && (val>0))
  163. printf("Total download time: %lu.%06lu sec.\n",
  164. (unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
  165. /* check for average download speed */
  166. res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD_T, &val);
  167. if((CURLE_OK == res) && (val>0))
  168. printf("Average download speed: %lu kbyte/sec.\n",
  169. (unsigned long)(val / 1024));
  170. if(prtall) {
  171. /* check for name resolution time */
  172. res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME_T, &val);
  173. if((CURLE_OK == res) && (val>0))
  174. printf("Name lookup time: %lu.%06lu sec.\n",
  175. (unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
  176. /* check for connect time */
  177. res = curl_easy_getinfo(curl_handle, CURLINFO_CONNECT_TIME_T, &val);
  178. if((CURLE_OK == res) && (val>0))
  179. printf("Connect time: %lu.%06lu sec.\n",
  180. (unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
  181. }
  182. }
  183. else {
  184. fprintf(stderr, "Error while fetching '%s' : %s\n",
  185. url, curl_easy_strerror(res));
  186. }
  187. /* cleanup curl stuff */
  188. curl_easy_cleanup(curl_handle);
  189. /* we are done with libcurl, so clean it up */
  190. curl_global_cleanup();
  191. return 0;
  192. }