chkspeed.c 6.7 KB

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