用C语言实现一个多线程下载器
时间: 2024-10-22 19:16:02 浏览: 23
在C语言中,实现一个多线程下载器通常会利用POSIX线程库(pthread库),配合网络编程库(如libcurl)。下面是一个基本示例,展示了如何创建两个线程分别下载两个URL:
```c
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <curl/curl.h>
#define THREAD_NAME_FORMAT "Thread-%d"
#define MAX_URL_LENGTH 1024
#define DOWNLOAD_DIR "./downloads"
// 下载函数
size_t download_data(void *ptr, size_t size, size_t nmemb, void *stream) {
FILE *fp = (FILE *) stream;
size_t total_size = size * nmemb;
if (fwrite(ptr, size, nmemb, fp) != size * nmemb) {
perror("Error writing to file");
return 0;
}
return total_size;
}
// 线程下载任务
void *download_thread(void *args) {
char url[MAX_URL_LENGTH], filename[128];
CURL *curl;
CURLcode res;
// 解析线程参数
strcpy(url, ((char*) args) + sizeof(int));
// 创建临时文件名
snprintf(filename, sizeof(filename), "%s/%s.tmp", DOWNLOAD_DIR, strstr(url, "/") + 1);
// 初始化curl
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (!curl) {
perror("Could not initialize cURL");
return NULL;
}
// 设置URL和目标文件
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, download_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) filename);
// 开始下载
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
return NULL;
}
// 完成并关闭curl
curl_easy_cleanup(curl);
// 将临时文件重命名为原文件名
rename(filename, filename + strlen(".tmp"));
pthread_exit(NULL);
}
int main() {
const char *urls[] = {"http://example.com/file1.txt", "http://example.com/file2.jpg"};
pthread_t threads[2];
// 初始化线程
for (int i = 0; i < 2; i++) {
pthread_create(&threads[i], NULL, download_thread, (void *) (urls[i] + sizeof("http://example.com/")));
}
// 等待所有线程完成
for (int i = 0; i < 2; i++) {
pthread_join(threads[i], NULL);
}
// 清理cURL全局环境
curl_global_cleanup();
return 0;
}
```
这个例子中,我们创建了两个线程,每个线程负责下载一个指定的URL,并将结果保存到本地文件。
阅读全文