接收邮件,支持自定义端口,SSL连接 自定义端口,跟SSL连接,网站找了好多 没找到SSL连接的。求帮助 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 本帖最后由 VisualEleven 于 2010-09-20 09:01:09 编辑 如下类代码,连接 POP3(ssl)服务器,供参考BOOL CPOP3::Connect(){ char *p,*b; sockaddr_in sin; unsigned int iLen=0; char sz[256] ={0}; if(m_bSSL) { int err=-1; SSLeay_add_ssl_algorithms(); m_meth = SSLv23_client_method(); SSL_load_error_strings(); m_ctx = SSL_CTX_new (m_meth); if(m_ctx == NULL) { SetLastError(ME_SSL); return FALSE; } m_sock = socket (AF_INET, SOCK_STREAM, 0); if (m_sock == INVALID_SOCKET) { SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_CREATE); return FALSE; } sin.sin_family = AF_INET; sin.sin_port = htons( (unsigned short)m_iPort); struct hostent * host_addr = gethostbyname(m_szHost); if(host_addr==NULL) { SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_HOST); return FALSE; } sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ; //****************************** int TimeOut=300000; if(::setsockopt(m_sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR) { closesocket(m_sock); SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_OPT); return FALSE; } TimeOut=900000; if(::setsockopt(m_sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR) { closesocket(m_sock); SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_OPT); return FALSE; } //设置非阻塞方式连接 unsigned long ul = 1; int ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul); if(ret==SOCKET_ERROR) { closesocket(m_sock); SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_OPT); return FALSE; } //连接 connect(m_sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR struct timeval timeout ; fd_set r; FD_ZERO(&r); FD_SET(m_sock, &r); timeout.tv_sec = SSL_CNT_TIMEOUT; timeout.tv_usec =0; ret = select(0, 0, &r, 0, &timeout); if ( ret <= 0 ) { ::closesocket(m_sock); SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_OPT); return FALSE; } unsigned long ul1= 0 ; ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul1); if(ret == SOCKET_ERROR) { ::closesocket (m_sock); SSL_CTX_free (m_ctx); SetLastError(ME_SOCK_OPT); return FALSE; } //************************ m_ssl = SSL_new (m_ctx); if(m_ssl == NULL) { SetLastError(ME_SSL); ::closesocket (m_sock); SSL_CTX_free (m_ctx); return FALSE; } SSL_set_fd (m_ssl, m_sock); err = SSL_connect (m_ssl); if(err == -1) { SetLastError(ME_SSL); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } //-- connect mess-- p = m_sz; b = p; iLen = 0; memset(p,'\0',MAX_POP3_GET_LEN); while(SSL_read (m_ssl, p,1) > 0) { if((iLen++) >= MAX_POP3_GET_LEN) break; if(*p == 10) { if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break; b = p+1; } p++; } //Disp(m_sz); if(iLen < 1) { SetLastError(ME_SOCK_CONNECT); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } if(m_sz[0] != '+') { SetLastError(ME_SOCK_CONNECT); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } //--USER sprintf(sz, "USER %s\r\n", m_szAc); err = SSL_write (m_ssl, sz,strlen(sz)); if(err == -1) { SetLastError(ME_AUTH); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } p = m_sz; b = p; iLen = 0; memset(p,'\0',MAX_POP3_GET_LEN); while(SSL_read(m_ssl, p,1) > 0) { if((iLen++) >= MAX_POP3_GET_LEN) break; if(*p == 10) { if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break; b = p+1; } p++; } //Disp(m_sz); if(iLen < 1) { SetLastError(ME_AUTH); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } if(m_sz[0] != '+') { SetLastError(ME_SOCK_CONNECT); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } //--PASS sprintf(sz, "PASS %s\r\n", m_szPwd); err = SSL_write (m_ssl, sz,strlen(sz)); if(err == -1) { SetLastError(ME_AUTH); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } p = m_sz; b = p; iLen = 0; memset(p,'\0',MAX_POP3_GET_LEN); while(SSL_read (m_ssl, p,1) > 0) { if((iLen++) >= MAX_POP3_GET_LEN) break; if(*p == 10) { if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break; b = p+1; } p++; } //Disp(m_sz); if(iLen < 1) { SetLastError(ME_AUTH); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } if(m_sz[0] != '+') { SetLastError(ME_SOCK_CONNECT); SSL_shutdown (m_ssl); closesocket(m_sock); SSL_free (m_ssl); SSL_CTX_free (m_ctx); return FALSE; } //-- OK -- } else { ; } m_bConnect = TRUE; return TRUE;} 由于是pop3的一个封装类,connect是类的方法之一里面有些函数调用不用管它,比如SetLastError,不过是为了错误跟踪,可以注销掉其中的类变量(m_XXXXX)通过变量名就可以识别了将这些代码略作精简整理,提供合适的变量申明,就可以直接使用了以上是建立连接的过程POP3的其它通信命令就很easy了 POP3通常在连接之后要进行一系统的操作,所以封装为类是必须的(将连接属性保持在类中),连接一旦建立就可以一直使用 BOOL EasySslClient::Connect(const char * address, const unsigned int port){ if(!m_inited) return FALSE; //如果未关闭则先关闭 if(!m_closed) Close(); // 创建 socket if (!tcp.Create()){ strcpy_s(LastErrorMsg,sizeof(LastErrorMsg),tcp.LastErrorMsg); return FALSE; } BOOL ret = tcp.Connect(address,port); ERR_clear_error(); if(ret) { ssl = SSL_new((SSL_CTX *)ctx); SSL_set_fd((SSL*)ssl, tcp.GetSocket()); /* 建立 SSL 连接 */ if (SSL_connect((SSL*)ssl) == -1) { int ssl_error = SSL_get_error((SSL*)ssl, ret); sprintf_s(LastErrorMsg,sizeof(LastErrorMsg),"SSL连接出错:",ERR_error_string(ERR_get_error(), NULL)); elog->Print(1,LastErrorMsg); } else { m_closed = FALSE; //printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); ShowCerts((SSL *)ssl); } } else { sprintf_s(LastErrorMsg,sizeof(LastErrorMsg),tcp.LastErrorMsg); } return ret; } 楼上的,这个不是全部的活。 我就是不知道其中一个环节,收取邮件的, JMail 我知道怎么弄 就是不能SSL这个我没研究好 求助,MFC程序运行时出现空白错误提示框,求解决,谢谢~ CTabView 问题 Dll向EXE发送自定义消息,很棘手。。。。。高手进。。 现在学com还有用么? 在ODBC中SQLConfigDataSource()函数在MFC中属于那个头文件,或那个类 消息问题! 怎样实现"Mirisoft Web浏览器"控件的打印功能? 哪里有关于用VC++编网络程序的电子书? C++基础,求解答,求秒杀 vs2010中CLR中用窗口控件button按钮播放音乐怎么具体操作 怎么判断CBitmap是否已经加载了图片 list box中输出一个表格
BOOL CPOP3::Connect()
{
char *p,*b;
sockaddr_in sin;
unsigned int iLen=0;
char sz[256] ={0}; if(m_bSSL)
{
int err=-1;
SSLeay_add_ssl_algorithms();
m_meth = SSLv23_client_method();
SSL_load_error_strings();
m_ctx = SSL_CTX_new (m_meth);
if(m_ctx == NULL)
{
SetLastError(ME_SSL);
return FALSE;
}
m_sock = socket (AF_INET, SOCK_STREAM, 0);
if (m_sock == INVALID_SOCKET)
{
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_CREATE);
return FALSE;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)m_iPort); struct hostent * host_addr = gethostbyname(m_szHost);
if(host_addr==NULL)
{
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_HOST);
return FALSE;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ; //******************************
int TimeOut=300000;
if(::setsockopt(m_sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(m_sock);
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_OPT);
return FALSE;
}
TimeOut=900000;
if(::setsockopt(m_sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(m_sock);
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_OPT);
return FALSE;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(m_sock);
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_OPT);
return FALSE;
} //连接
connect(m_sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r; FD_ZERO(&r);
FD_SET(m_sock, &r);
timeout.tv_sec = SSL_CNT_TIMEOUT;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(m_sock);
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_OPT);
return FALSE;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(m_sock, FIONBIO, (unsigned long*)&ul1);
if(ret == SOCKET_ERROR)
{
::closesocket (m_sock);
SSL_CTX_free (m_ctx);
SetLastError(ME_SOCK_OPT);
return FALSE;
}
//************************
m_ssl = SSL_new (m_ctx);
if(m_ssl == NULL)
{
SetLastError(ME_SSL);
::closesocket (m_sock);
SSL_CTX_free (m_ctx);
return FALSE;
}
SSL_set_fd (m_ssl, m_sock);
err = SSL_connect (m_ssl);
if(err == -1)
{
SetLastError(ME_SSL);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
}
//-- connect mess--
p = m_sz;
b = p;
iLen = 0;
memset(p,'\0',MAX_POP3_GET_LEN);
while(SSL_read (m_ssl, p,1) > 0)
{
if((iLen++) >= MAX_POP3_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break;
b = p+1;
}
p++;
} //Disp(m_sz); if(iLen < 1)
{
SetLastError(ME_SOCK_CONNECT);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} if(m_sz[0] != '+')
{
SetLastError(ME_SOCK_CONNECT);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} //--USER
sprintf(sz,
"USER %s\r\n",
m_szAc); err = SSL_write (m_ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} p = m_sz;
b = p;
iLen = 0;
memset(p,'\0',MAX_POP3_GET_LEN);
while(SSL_read(m_ssl, p,1) > 0)
{
if((iLen++) >= MAX_POP3_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break;
b = p+1;
} p++;
} //Disp(m_sz); if(iLen < 1)
{
SetLastError(ME_AUTH);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} if(m_sz[0] != '+')
{
SetLastError(ME_SOCK_CONNECT);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} //--PASS
sprintf(sz,
"PASS %s\r\n",
m_szPwd);
err = SSL_write (m_ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} p = m_sz;
b = p;
iLen = 0;
memset(p,'\0',MAX_POP3_GET_LEN);
while(SSL_read (m_ssl, p,1) > 0)
{
if((iLen++) >= MAX_POP3_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ' || b[0] == '-' || b[3] == '\r') break;
b = p+1;
}
p++;
} //Disp(m_sz);
if(iLen < 1)
{
SetLastError(ME_AUTH);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
} if(m_sz[0] != '+')
{
SetLastError(ME_SOCK_CONNECT);
SSL_shutdown (m_ssl);
closesocket(m_sock);
SSL_free (m_ssl);
SSL_CTX_free (m_ctx);
return FALSE;
}
//-- OK --
}
else
{
;
} m_bConnect = TRUE;
return TRUE;
}
里面有些函数调用不用管它,比如SetLastError,不过是为了错误跟踪,可以注销掉
其中的类变量(m_XXXXX)通过变量名就可以识别了
将这些代码略作精简整理,提供合适的变量申明,就可以直接使用了以上是建立连接的过程
POP3的其它通信命令就很easy了
BOOL EasySslClient::Connect(const char * address, const unsigned int port)
{
if(!m_inited)
return FALSE; //如果未关闭则先关闭
if(!m_closed)
Close(); // 创建 socket
if (!tcp.Create()){
strcpy_s(LastErrorMsg,sizeof(LastErrorMsg),tcp.LastErrorMsg);
return FALSE;
} BOOL ret = tcp.Connect(address,port);
ERR_clear_error();
if(ret)
{
ssl = SSL_new((SSL_CTX *)ctx);
SSL_set_fd((SSL*)ssl, tcp.GetSocket());
/* 建立 SSL 连接 */
if (SSL_connect((SSL*)ssl) == -1)
{ int ssl_error = SSL_get_error((SSL*)ssl, ret);
sprintf_s(LastErrorMsg,sizeof(LastErrorMsg),"SSL连接出错:",ERR_error_string(ERR_get_error(), NULL));
elog->Print(1,LastErrorMsg);
}
else
{
m_closed = FALSE;
//printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
ShowCerts((SSL *)ssl);
} }
else
{
sprintf_s(LastErrorMsg,sizeof(LastErrorMsg),tcp.LastErrorMsg);
}
return ret;
}
楼上的,这个不是全部的活。 我就是不知道其中一个环节,收取邮件的, JMail 我知道怎么弄 就是不能SSL
这个我没研究好