10 网络库
约 1780 字大约 6 分钟
2025-06-22
<curl/curl.h> libcurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP这些协议,同时支持使用SSL证书的安全文件传输:HTTP POST, HTTP PUT, FTP 上传, 基于HTTP形式的上传、代理、Cookies、用户加密码的认证等多种应用场景。另外,libcurl是一个高移植性的库,能在绝大多数系统上运行,包括Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, UnixWare, HURD, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS等。
编译链接
-lcurl
打印当前libcurl版本
char* curl_version()
1. 调用curl_global_init()初始化libcurl
这个函数只能用一次。(在调用curl_global_cleanup 函数后仍然可再用)
如果这个函数在curl_easy_init函数调用时还没调用,它讲由libcurl库自动调用,所以多线程下最好主动调用该函数以防止在线程中curl_easy_init时多次调用。
[!warning] Title 虽然libcurl是线程安全的,但curl_global_init是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。
- flags
CURL_GLOBAL_ALL: 初始化所有的可能的调用。
CURL_GLOBAL_SSL: 初始化支持安全套接字层。
CURL_GLOBAL_WIN32: 初始化win32套接字库。
CURL_GLOBAL_NOTHING: 没有额外的初始化。 - return: 返回 CURLE_OK 为成功,返回其他值失败
CURLcode curl_global_init(long flags);
2. 调用curl_easy_init()函数得到 easy interface型指针
初始化一个CURL类型的指针,要在 curl_easy_cleanup 中进行释放。 返回一个easy_handle(CURL指针), 一般都用在easy系列的函数中.
CURL * curl_easy_init()
重新初始化CURL指针为默认值
void curl_easy_reset(CURL *curl)
3. 调用curl_easy_setopt()设置传输选项
- curl : curl_easy_init 返回的 CURL类型指针
- option :参数选项
- return:返回 CURLE_OK 为成功,返回其他值失败
CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ... );
如果没有通过CURLOPT_WRITEFUNCTION属性给easy handle设置回调函数,libcurl会提供一个默认的回调函数,它只是简单的将接收到的数据打印到标准输出。 回调函数的调用是在每次socket接收到数据之后,并不是socket接收了所有的数据,然后才调用设定的回调函数 常见选项
选项 | 作用 |
---|---|
CURLOPT_URL | 设置要访问的URL |
CURLOPT_WRITEFUNCTION | 设置回调函数,回调函数在libcurl接收到数据后被调用 回调函数原型: size_t function(void *ptr, size_t size, size_t nmemb, void *stream); |
CURLOPT_WRITEDATA | 用于表明 CURLOPT_WRITEFUNCTION 函数中的stream指针的来源 |
CURLOPT_HEADERFUNCTION | 设置回调函数,回调函数在libcurl接收到http响应头后被调用 回调函数原型 : size_t function( void *ptr, size_t size,size_t nmemb, void *stream); |
CURLOPT_HEADERDATA | 表明CURLOPT_HEADERFUNCTION 函数的stream指针的来源。 |
CURLOPT_TIMEOUT | 设置数据传输超时时间 |
CURLOPT_CONNECTIONTIMEOUT | 设置连接超时时间 |
CURLOPT_POST | 设置请求方式为post |
CURLOPT_POSTFIELDS | 设置post请求体 |
CURLOPT_POSTFIELDSIZE | 设置post请求大小 |
CURLOPT_HTTPHEADER | 设置http请求头 |
CURLOPT_SSL_VERIFYPEER | 设置是否验证对端证书,设置为0表示不验证。默认为1,表示验证。 |
CURLOPT_SSL_VERIFYHOST | 设置是都验证服务器证书,设置为0表示不验证。 |
4. 调用curl_easy_perform()函数完成传输任务
在初始化CURL类型的指针以及curl_easy_setopt完成后调用 以阻塞方式执行请求
- curl :curl_easy_init 返回的 CURL类型指针
- return:返回 CURLE_OK为成功,返回其他值失败
CURLcode curl_easy_perform(CURL* handle)
宏对应的含义
宏 | 含义 |
---|---|
CURLE_OK | 任务完成一切都好 |
CURLE_UNSUPPORTED_PROTOCOL | 不支持的协议,由URL的头部指定 |
CURLE_COULDNT_CONNECT | 不能连接到remote 主机或者代理 |
CURLE_REMOTE_ACCESS_DENIED | 访问被拒绝 |
CURLE_HTTP_RETURNED_ERROR | http返回错误 |
CURLE_READ_ERROR | 读本地文件错误 |
- 请求会话中的相关信息
- curl:curl_easy_init 返回的 CURL类型指针
- info CURLINFO_RESPONSE_CODE :获取http状态码 其他参数描述
- return:返回 CURLE_OK为成功,返回其他值失败
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... )
6. 调用curl_easy_cleanup()释放内存 清理 curl_easy_init 接口申请的 CURL 类型指针
void curl_easy_cleanup(CURL* handle)
- 调用curl_global_cleanup()析构libcurl
[!warning] Title 虽然libcurl是线程安全的,但curl_global_cleanup是不能保证线程安全的,所以不要在每个线程中都调用curl_global_init,应该将该函数的调用放在主线程中。
结束libcurl使用的时候,用来对curl_global_init做的工作清理。类似于close的函数。
void curl_global_cleanup(void)
示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <iostream>
typedef struct {
std::string body;
size_t bodySize;
} stResponse;
typedef struct {
std::string header;
size_t headerSize;
} stResponseHeader;
size_t responseBodyCallback(void *ptr, size_t size, size_t nmemb, void *stream) {
stResponse* pResponse = (stResponse*)stream;
pResponse->body.append((char*)ptr, size * nmemb);
pResponse->bodySize = size * nmemb;
return size * nmemb;
}
size_t responseHeaderCallback(void *ptr, size_t size, size_t nmemb, void *stream){
stResponseHeader* pResponseHeader = (stResponseHeader*)stream;
pResponseHeader->header.append((char*)ptr, size * nmemb);
pResponseHeader->headerSize = size * nmemb;
return size * nmemb;
}
int main(){
std::string readBuffer;
stResponse response;
stResponseHeader responseHeader;
// 初始化所有可能的调用
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
// 设置url
curl_easy_setopt(curl, CURLOPT_URL, "http://182.92.205.179:10088");
// 设置post请求,不设置或设置为0则为get请求
curl_easy_setopt(curl, CURLOPT_POST, 1);
// 设置post请求体
char postData[1024] = "{\"req\":\"hello\"}";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData);
// 设置post请求体大小
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(postData));
// 设置http请求头
curl_slist* headerList = NULL;
headerList = curl_slist_append(headerList, "Content-Type: application/json");
headerList = curl_slist_append(headerList, "flag: libcurl");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);
// 设置不校验证书,https请求时使用
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// 设置回调函数获取响应体数据
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, responseBodyCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&response);
// 设置回调函数获取响应头数据
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, responseHeaderCallback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void*)&responseHeader);
// 超时时间
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5);
// 执行请求
CURLcode res = curl_easy_perform(curl);
// 检查错误
if(res == CURLE_OK){
// 获取状态码
int responseCode = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &responseCode);
std::cout << "code : "<<responseCode << std::endl;
std::cout << "responseHeader size : "<<responseHeader.headerSize << std::endl;
std::cout << "responseHeader header : "<<responseHeader.header.c_str() << std::endl;
std::cout << "response size : "<<response.bodySize << std::endl;
std::cout << "response body : "<<response.body.c_str() << std::endl;
}else{
std::cout<<curl_easy_strerror(res)<<std::endl;
}
curl_slist_free_all(headerList);
// 清理
curl_easy_cleanup(curl);
return 0;
}
libevent
以 cst 用户登录为例
- 下载 官网:http://libevent.org/
- 将压缩包拷贝到Linux 系统中,放在/home/cst 中
- 假设当前目录为/home/cst , 解压缩
tar xvzf libevent-2.1.10-stable.tar.gz
- 新建文件夹,放置安装 libevent 后的文件
mkdir/usr/lib/libevent
- 安装过程,假设当前目录为/home/cst 进入到解压缩后的文件夹中
cd libevent-2.1.10-stable
配置
./configure -prefix=/usr/lib/libevent--disable-openssl
编译
make
安装,如果涉及权限问题,需要 sudo。
sudo make install
- 拷贝头文件和库文件 进入/usr/lib/libevent 中
cd /usr/lib/libevent
查看当前目录中有哪些文件
ls
ls正常会看到include 和 lib文件夹 拷贝头文件
sudo cp include/* /usr/include -ar
拷贝库文件
sudo cp lib/lib* /usr/lib -ar
更新动态库路径
sudo /sbin/ldconfig -v
- 安装完测试 进入解压缩后的libevent-2.1.10-stable\sample 中,编译命令后加-levent
gcc hello-world.c -o hello-world -levent
成功产生 hello-world 可执行文件 在终端1命令行输入:
./hello-world
在终端2命令行输入:
nc 127.0.0.1 9995
终端1输出:flushed answer,终端2 输出:Hello,World! 即为安装成功
贡献者
版权所有
版权归属:PinkDopeyBug