我使用libcurl C库来访问(获取,搜索)gmail imaps服务器,我使用libcurl示例中的代码,即" imap-ssl.c"作为一个测试的例子。第一次执行时的示例代码工作正常并从我的gmail帐户中获取所需的电子邮件,但是当您再次尝试执行该程序时,当想要再次获取不同的电子邮件或同一个电子邮件时,它会失败, 但如果我在大约20分钟后重新运行该程序,它就可以运行并获取所需的邮件。
似乎gmail要求我们立即从服务器获取整个收件箱,即本地(已提取)电子邮件与在线gmail服务器的同步只允许在20分钟内完成一次或者什么。如果一个人一次只想访问一封电子邮件或者只是逐个浏览他的整个Gmail邮件收件箱邮件怎么办?
此外,我尝试使用openssl命令行工具在imap.gmail.com:993(启用ssl)上获取或执行imaps命令,它就像一个魅力,无论我多少次尝试访问gmail它永远不会说一句麻烦,但libcurl确实如此。
#include<stdio.h>
#include<string.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res = CURLE_OK;
curl = curl_easy_init();
if(curl) {
/* Set username and password */
curl_easy_setopt(curl, CURLOPT_USERNAME, "example@gmail.com");
curl_easy_setopt(curl, CURLOPT_PASSWORD, "examplepassword");
/* This will fetch message 1 from the user's inbox. Note the use of
* imaps:// rather than imap:// to request a SSL based connection. */
curl_easy_setopt(curl, CURLOPT_URL,"imaps://imap.gmail.com:993/INBOX/;UID=5");
/* Note: CA cert is already in the right place (checked) */
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
/* If the site you're connecting to uses a different host name that what
* they have mentioned in their server certificate's commonName (or
* subjectAltName) fields, libcurl will refuse to connect. You can skip
* this check, but this will make the connection less secure. */
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
#endif
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* Perform the fetch */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
return (int)res;
}
> * Hostname was NOT found in DNS cache
> * Trying 74.125.206.109...
> * Connected to imap.gmail.com (74.125.206.109) port 993 (#0)
> * successfully set certificate verify locations:
> * CAfile: none
> > CApath: /etc/ssl/certs
> * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
> * Server certificate:
> * subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=imap.gmail.com
> * start date: 2017-03-22 16:46:00 GMT
> * expire date: 2017-06-14 16:17:00 GMT
> * subjectAltName: imap.gmail.com matched
> * issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
> * SSL certificate verify ok.
> * OK Gimap ready for requests from 182.180.90.60
> * A001 CAPABILITY
> > CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN
> AUTH=PLAIN-CLIENTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH A001 OK Thats all
> she wrote! 9
> * A002 AUTHENTICATE PLAIN
> * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH
> UTF8=ACCEPT LIST-EXTENDED LIST-STATUS LITERAL- SPECIAL-USE
> APPENDLIMIT=35651584
> * A002 OK example@gmail.com authenticated (Success)
> * A003 SELECT INBOX
> * FLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing)
> * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $NotPhishing $Phishing \*)] Flags permitted.
> * OK [UIDVALIDITY 1] UIDs valid.
> * 32 EXISTS
> * 0 RECENT
> * OK [UIDNEXT 46] Predicted next UID.
> * OK [HIGHESTMODSEQ 4777]
> * A003 OK [READ-WRITE] INBOX selected. (Success)
> * A004 FETCH 5 BODY[]
> * 5 FETCH (BODY[] {628}
> *Found 628 bytes to download
> > Bcc: example@gmail.com
> > Return-Path: <example@gmail.com>
> > Received: from localhost (["MY IP Address])
> > by smtp.gmail.com with ESMTPSA id
> > for <example@gmail.com>
> > (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
> > Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * Message-ID: <"msg id"@mx.google.com>
> * Date: Wed, 15 Mar 2017 03:13:29 -0700 (PDT)
> * From: example@gmail.com
> > Written 489 bytes, 139 bytes are left for transfer
> > Hi, i'm using openssl to send this message, i hope you are doing great man
> > Thank you so much
> > I just wanted to tell you that this is also possible
> * A004 OK Success
> * Connection #0 to host imap.gmail.com left intact
> * Hostname was NOT found in DNS cache
> * Trying 74.125.133.108...
> * Trying 2a00:1450:400c:c07::6d...
> * connect to 2a00:1450:400c:c07::6d port 993 failed: Network is unreachable
>* Failed to connect to imap.gmail.com port 993: Network is unreachable
>* Closing connection 0
>>curl_easy_perform() failed: Couldn't connect to server
任何代码示例都会非常感激。
P.S:已添加代码
答案 0 :(得分:0)
在第二次尝试时,它无法连接到imap服务器,但这与libcurl无关。
您可以添加以下代码以确保它仅通过IPv4连接,然后调试输出中的错误消息将是从连接尝试到与您更相关的IPv4地址(因为您很可能不会#39) ;有IPv6支持):
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
此处有关该选项的更多信息: https://curl.haxx.se/libcurl/c/CURLOPT_IPRESOLVE.html
尝试使用完全相同的IP连接到端口993,因为libcurl程序在libcurl程序不起作用时尝试通过telnet连接。我确定它也会失败。
前进的方法可能会调查你是否有某种可能导致问题的防火墙。尝试运行tcpdump(或者如果你想要一个GUI,则运行wireshark)来查看TCP级别上发生的事情。