您的位置:首页 > 移动开发 > IOS开发

ios基于libcurl发送带附件邮件

2017-09-26 19:19 896 查看
最近开发,为了查看日志文件,引入日志及邮件发送功能

日志使用的是boost库,邮件功能是使用libcurl库,分享下

后续把压缩上传功能加上

邮件发送功能,示例代码使用了一个第三方的类和个api的两个例子,可以参考
[github](https://github.com/billnie/Exam)


/*
* This is the list of basic details you need to tweak to get things right.
*/
#define USERNAME "xj.nie@exam.com.cn"
#define PASSWORD "***"
#define SMTPSERVER "smtp.exam.com.cn"
#define SMTPPORT ":25" /* it is a colon+port string, but you can set it
to "" to use the default port */
#define RECIPIENT "<706919534@qq.com>"
#define MAILFROM "<xj.nie@exam.com.cn>"

#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000

/* Note that you should include the actual meta data headers here as well if
you want the mail to have a Subject, another From:, show a To: or whatever
you think your mail should feature! */

static struct timeval tvnow(void)
{
/*
** time() returns the value of time in seconds since the Epoch.
*/
struct timeval now;
now.tv_sec = (long)time(NULL);
now.tv_usec = 0;
return now;
}

static long tvdiff(struct timeval newer, struct timeval older)
{
return (newer.tv_sec-older.tv_sec)*1000+
(newer.tv_usec-older.tv_usec)/1000;
}

#define FROM     "<xj.nie@exam.com.cn>"
#define TO       "<706919534@qq.com>"
#define CC       "<xj.nie@exam.com.cn>"
static const char *payload_text[] = {
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",
"To: " TO "\r\n",
"From: " FROM "(Example User)\r\n",
"Cc: " CC "(Another example User)\r\n",
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@"
"rfcpedant.example.org>\r\n",
"Subject: App-log\r\n",
"\r\n", /* empty line to divide headers from body, see RFC5322 */
"This is the App ios app logs.\r\n",
"\r\n",
"It could be a lot of lines, could be MIME encoded, whatever.\r\n",
"Check RFC5322.\r\n",
NULL
};

struct upload_status {
int lines_read;
};

static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct upload_status *upload_ctx = (struct upload_status *)userp;
const char *data;

if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
return 0;
}

data = payload_text[upload_ctx->lines_read];

if(data) {
size_t len = strlen(data);
memcpy(ptr, data, len);
upload_ctx->lines_read++;

return len;
}

return 0;
}

int vmain(void)
{
CURL *curl;
CURLM *mcurl;
int still_running = 1;
struct timeval mp_start;
struct curl_slist *recipients = NULL;
struct upload_status upload_ctx;

upload_ctx.lines_read = 0;

curl_global_init(CURL_GLOBAL_DEFAULT);

curl = curl_easy_init();
if(!curl)
return 1;

mcurl = curl_multi_init();
if(!mcurl)
return 2;

/* This is the URL for your mailserver */
curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.protruly.com.cn:25");

/* Note that this option isn't strictly required, omitting it will result in
* libcurl sending the MAIL FROM command with empty sender data. All
* autoresponses should have an empty reverse-path, and should be directed
* to the address in the reverse-path which triggered them. Otherwise, they
* could cause an endless loop. See RFC 5321 Section 4.5.5 for more details.
*/
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);

/* Add two recipients, in this particular case they correspond to the
* To: and Cc: addressees in the header, but they could be any kind of
* recipient. */
recipients = curl_slist_append(recipients, TO);
//    recipients = curl_slist_append(recipients, CC);
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

/* We're using a callback function to specify the payload (the headers and
* body of the message). You could just use the CURLOPT_READDATA option to
* specify a FILE pointer to read from. */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
/* Tell the multi stack about our easy handle */
curl_multi_add_handle(mcurl, curl);

/* Record the start time which we can use later */
mp_start = tvnow();

/* We start some action by calling perform right away */
curl_multi_perform(mcurl, &still_running);

while(still_running) {
struct timeval timeout;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
int rc;
CURLMcode mc; /* curl_multi_fdset() return code */

long curl_timeo = -1;

/* Initialise the file descriptors */
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);

/* Set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;

curl_multi_timeout(mcurl, &curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}

/* get file descriptors from the transfers */
mc = curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);

if(mc != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}

/* On success the value of maxfd is guaranteed to be >= -1. We call
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
to sleep 100ms, which is the minimum suggested value in the
curl_multi_fdset() doc. */

if(maxfd == -1) {
#ifdef _WIN32
Sleep(100);
rc = 0;
#else
/* Portable sleep for platforms other than Windows. */
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
rc = select(0, NULL, NULL, NULL, &wait);
#endif
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
}

if(tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
fprintf(stderr,
"ABORTING: Since it seems that we would have run forever.\n");
break;
}

switch(rc) {
case -1:  /* select error */
break;
case 0:   /* timeout */
default:  /* action */
curl_multi_perform(mcurl, &still_running);
break;
}
}

/* Free the list of recipients */
curl_slist_free_all(recipients);

/* Always cleanup */
curl_multi_remove_handle(mcurl, curl);
curl_multi_cleanup(mcurl);
curl_easy_cleanup(curl);
curl_global_cleanup();

return 0;
}
int main()
{
//    vmain();
//    xmain();
std::vector<std::string> secret =
{
};

std::vector<std::string> to =
{
"706919534@qq.com"
};

std::vector<std::string> cc =
{

};

std::vector<std::string> attach =
{
"/Users/zzx/up.txt"
};

CurlSmtp* mail = new CurlSmtp("xj.nie@exam.com.cn"
, "****"
, to
, secret
, cc
, attach
, "DialChat-app log"
, "This is App ios app log file"
, "smtp.exam.com.cn"
, "25");    //qq587

mail->send_mail();
sleep(5);

// send another mail
//  mail->set_from("bingley_li@maxmob.cn");
//  mail->set_password("adfsf");
//  mail->set_subject("test2");
//  mail->set_message("another boy hehe hahah");
//  mail->set_server(SMTP_SERVER);
//  mail->set_port(SMTP_PORT);
//
//  cc.clear();
//  cc.push_back("godsb@qq.com");
//  mail->set_cc(cc);
//
//  to.clear();
//  to.push_back("honeyligo@sina.com");
//  mail->set_to(to);
//
//  attach.clear();
//  attach.push_back("./1.png");
//  mail->set_attach(attach);
//
//  mail->send_mail();

sleep(5);
delete mail;

return 0;
}


ios使用

int sendmail(const char *url)
{

std::vector<std::string> secret =
{
};

std::vector<std::string> to =
{
"706919534@qq.com"
};

std::vector<std::string> cc =
{

};

std::vector<std::string> attach =
{
};
if(url ){
attach.push_back(url);
}
CurlSmtp* mail = new CurlSmtp("xj.nie@exam.com.cn"
, "bql-1234"
, to
, secret
, cc
, attach
, "App-app log"
, "This is App ios app log file"
, "smtp.exam.com.cn"
, "25");    //qq587

mail->send_mail();

delete mail;

return 0;
}

//调用
-(RACSignal* ) requsetMailLog:(NSString *)file{
RACSignal *signal;
signal = [RACSignal createSignal: ^RACDisposable *(id<RACSubscriber> subscriber) {
dispatch_async(dispatch_get_global_queue(0, 0),^(void){
int ret;
ret = sendmail([file cStringUsingEncoding:NSUTF8StringEncoding]);
[subscriber sendNext:[NSNumber numberWithInt:ret]];
[subscriber sendCompleted];
});
return nil;
}];
return signal;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  libcurl