如何解决是否可以在没有基于文件描述符的套接字的情况下使用libcurl?
我使用自定义的读写套接字函数编写了以下libcurl代码:
//...
CURL *curl;
FILE *fp;
CURLcode res;
char outfilename[FILENAME_MAX] = "file";
curl = curl_easy_init();
/* no progress meter please */
//curl_easy_setopt(curl,CURLOPT_NOPROGRESS,1L);
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,&sharedValue);
curl_easy_setopt(curl,CURLOPT_READFUNCTION,read_data);
curl_easy_setopt(curl,CURLOPT_READDATA,CURLOPT_OPENSOCKETFUNCTION,opensocket);
curl_easy_setopt(curl,CURLOPT_OPENSOCKETDATA,CURLOPT_CLOSESOCKETFUNCTION,closecb);
curl_easy_setopt(curl,CURLOPT_CLOSESOCKETDATA,CURLOPT_URL,hostname.c_str());
curl_easy_setopt(curl,CURLOPT_SOCKOPTFUNCTION,sockopt_callback);
curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
我不知道该怎么处理CURLOPT_SOCKOPTFUNCTION
,所以我做了sockopt_callback
,
static curl_socket_t opensocket(void *clientp,curlsocktype purpose,struct curl_sockaddr *address)
{
return 0;
}
但是我明白了
* Trying 212.183.159.230:80...
* Could not set TCP_NODELAY: Socket operation on non-socket
* connect to 212.183.159.230 port 80 failed: Socket operation on non-socket
libcurl wants to close 0 now
因为可能正在尝试写入套接字0
。显然,我不能阻止它调用套接字上的选项,例如设置TCP_NODELAY
和最重要的connect
。
是否可以使libcurl永远不调用套接字文件描述符?
我的一个想法是传递一个现有的套接字作为libcurl的虚拟对象,然后仍然使用我的写入和读取功能。但是,libcurl只是通过套接字发送内容,而不是通过write和read函数发送
解决方法
我以为write_data
是重定向套接字调用的一种方法,但它与它无关,它实际上是一个写客户端收到的内容的函数。
但是,通过传递一个socketpair
(如@domen表示的那样),我使它起作用了!
素描:
//...
static curl_socket_t opensocket(void *clientp,curlsocktype purpose,struct curl_sockaddr *address)
{
auto *sharedValue = static_cast<SharedValue *>(clientp);
return sharedValue->curl_socket;
}
int socket_vector[2];
if (0 != socketpair(AF_UNIX,SOCK_STREAM,socket_vector))
{
std::cout << "problem creating socketpair" << std::endl;
std::exit(2);
}
sharedValue.curl_socket = socket_vector[0];
sharedValue.vpn_socket = socket_vector[1];
//writes the result to a file
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,write_data_file);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,destFile);
curl_easy_setopt(curl,CURLOPT_OPENSOCKETFUNCTION,opensocket);
curl_easy_setopt(curl,CURLOPT_OPENSOCKETDATA,&sharedValue);
curl_easy_setopt(curl,CURLOPT_CLOSESOCKETFUNCTION,closecb);
curl_easy_setopt(curl,CURLOPT_CLOSESOCKETDATA,CURLOPT_SOCKOPTFUNCTION,sockopt_callback);
curl_easy_setopt(curl,CURLOPT_URL,hostname.c_str());
//curl_easy_setopt(curl,CURLOPT_VERBOSE,1);
//Start a thread here that will read/write to the socket pair on the other endpoint (in my case vpn_socket)
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res)
{
std::cout << "libcurl error code: " << res << ",libcurl error: " << curl_easy_strerror(res) << std::endl;
return 1;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。