最近在使用libcurl异步收发消息时碰到一个问题,实在没头绪,有哪位大大可以帮忙看看,多谢
一、目标:使用multi interface实现消息异步收发,两个线程,一个线程发消息,另一个线程收消息
二、问题:
1、环回收发无问题,但是发送到其它IP有问题,抓包能建立TCP连接,但是马上会断开,没有发出数据
2、程序会发生段错误具体信息如下
(gdb) bt
#0 0x0000003d0e432222 in curl_multi_fdset (multi_handle=0x604120, read_fd_set=0x7ffff7fd4d00, write_fd_set=0x0, exc_fd_set=<value optimized out>,
max_fd=0x7ffff7fd4bfc) at multi.c:874
#1 0x0000000000400d08 in curl_multi_select (curl_m=0x604120) at curl_send.c:30
#2 0x0000000000400fb3 in curl_multi_recv () at curl_send.c:110
#3 0x0000003cf84079d1 in start_thread () from /lib64/libpthread.so.0
#4 0x0000003cf80e88fd in clone () from /lib64/libc.so.6
(gdb) f 0
#0 0x0000003d0e432222 in curl_multi_fdset (multi_handle=0x604120, read_fd_set=0x7ffff7fd4d00, write_fd_set=0x0, exc_fd_set=<value optimized out>,
max_fd=0x7ffff7fd4bfc) at multi.c:874
874 in multi.c
(gdb) f 1
#1 0x0000000000400d08 in curl_multi_select (curl_m=0x604120) at curl_send.c:30
30 curl_multi_fdset(curl_m, &fd_read, NULL, NULL, &max_fd);
(gdb)
三、代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <curl/curl.h>
CURLM *g_curl_m = NULL;
int curl_multi_select(CURLM *curl_m)
{
int ret = 0;
struct timeval timeout_tv;
fd_set fd_read;
fd_set fd_write;
fd_set fd_except;
int max_fd = -1;
if (NULL == curl_m)
{
return -1;
}
FD_ZERO(&fd_read);
FD_ZERO(&fd_write);
FD_ZERO(&fd_except);
timeout_tv.tv_sec = 1;
timeout_tv.tv_usec = 0;
curl_multi_fdset(curl_m, &fd_read, NULL, NULL, &max_fd);
if (-1 == max_fd)
{
return -1;
}
int select_ret = select(max_fd + 1, &fd_read, NULL, NULL, &timeout_tv);
if (-1 == select_ret)
{
ret = -1;
}
else
{
ret = 0;
}
return ret;
}
size_t save_response(void *buffer, size_t size, size_t nmemb, void *userp)
{
static int recv_times = 0;
recv_times++;
printf("recv response:\n%d\n", recv_times);
printf("%s\n", buffer);
return size * nmemb;
}
void curl_multi_send()
{
int send_times = 0;
int running_handle_count = 0;
char auth[32] = {0};
while(1)
{
CURL *easy_handle = NULL;
struct curl_slist *http_header = NULL;
send_times++;
memset(auth, 0, sizeof(auth));
easy_handle = curl_easy_init();
snprintf(auth, sizeof(auth), "Authorization:%d", send_times);
http_header = curl_slist_append(http_header, auth);
http_header = curl_slist_append(http_header, "User-Agent: freecwmp");
http_header = curl_slist_append(http_header, "Content-Type: text/xml");
http_header = curl_slist_append(http_header, "Expect:");
curl_easy_setopt(easy_handle, CURLOPT_URL, "http://guest:guest@10.55.0.156:9000/");
curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, http_header);
curl_easy_setopt(easy_handle, CURLOPT_POSTFIELDS, "");
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, save_response);
curl_multi_add_handle(g_curl_m, easy_handle);
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(g_curl_m, &running_handle_count))
{
}
printf("Success send http msg.\n");
usleep(10000000);
}
return;
}
void curl_multi_recv()
{
int msgs_left = 0;
int running_handles = 0;
CURLM *curl_m = NULL;
CURLMsg *msg = NULL;
curl_m = g_curl_m;
while(1)
{
if (0 == curl_multi_select(curl_m))
{
msgs_left = 0;
running_handles = 0;
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curl_m, &running_handles))
{
}
while ((msg = curl_multi_info_read(curl_m, &msgs_left)))
{
if (CURLMSG_DONE == msg->msg)
{
curl_multi_remove_handle(curl_m, msg->easy_handle);
}
}
}
usleep(100000);
}
return;
}
int main(int argc, char *argv[])
{
curl_global_init(CURL_GLOBAL_ALL);
g_curl_m = curl_multi_init();
pthread_t send_pid = {0};
pthread_t receive_pid = {0};
//pthread_attr_t attr = {0};
//pthread_attr_init(&attr);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&receive_pid, NULL, (void *) curl_multi_recv, NULL);
pthread_create(&send_pid, NULL, (void *) curl_multi_send, NULL);
//pthread_attr_destroy(&attr);
pthread_join(send_pid, NULL);
pthread_join(receive_pid, NULL);
curl_global_cleanup();
return 0;
}