文章作者:langouster
写软件时常要用到发邮件,我当时测试时遇到了不少的困难后来却发现原来是我的Mcafee一声不响地拦截了。
汗一下 …………
以下是用telnet发邮件的过程:
---------------------------
接收:220 163.com Coremail SMTP(Anti Spam) System
发送:helo 163.com
接收:250 OK
发送:ehlo 163.com
接收:250 OK
发送:auth login
接收:334 dXNlcm5hbWU6
发送:bGFuZ291c3Rlcg==
接收:334 UGFzc3dvcmQ6
发送:MTIzNDU2
接收:235 Authentication successful
发送:MAIL FROM:<langouster@163.com>
接收:250 Mail OK
发送:RCPT TO:<langouster@163.com>
接收:250 Mail OK
发送:DATA
接收:354 End data with <CR><LF>.<CR><LF>
发送: //开头有回车
f222222222222222222222222222
222222222222222222222222222
------------------------------ 回车.回车
.
接收:250 Mail OK queued as smtp1,wKjRCzaAjQcAsjNEEh0ABw==.35887S2
发送:quit
接收:221 Bye
-------------------------------------
用户名密码都是经过编码的。编码程序如下,这个不是我写的!
int encode64(const char *_in, unsigned inlen, char *_out, unsigned outmax, unsigned *outlen)
{
const unsigned char *in = (const unsigned char *)_in;
unsigned char *out = (unsigned char *)_out;
unsigned char oval;
char *blah;
unsigned olen;
static char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/* Will it fit? */
olen = (inlen + 2) / 3 * 4;
if (outlen)
*outlen = olen;
if (outmax < olen)
return -2;
/* Do the work... */
blah=(char *) out;
while (inlen >= 3) {
/* user provided max buffer size; make sure we don't go over it */
*out++ = basis_64[in[0] >> 2];
*out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = basis_64[in[2] & 0x3f];
in += 3;
inlen -= 3;
}
if (inlen > 0) {
/* user provided max buffer size; make sure we don't go over it */
*out++ = basis_64[in[0] >> 2];
oval = (in[0] << 4) & 0x30;
if (inlen > 1) oval |= in[1] >> 4;
*out++ = basis_64[oval];
*out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
*out++ = '=';
}
if (olen < outmax)
*out = '\0';
return 1;
}
///////////////////////////////////////////
以下是一个用163服务器发邮件的实例,这个是我写的:
unsigned short SendMail(char* MailUserName,char* MailUserPass,char *ReceMail,char* Info)
{
WSADATA wsaData;
WSAStartup(MAKEWORD( 2,2 ),&wsaData);
SOCKET fsocket;
fsocket = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP );
char strsend[500]={0},strrecv[500]={0};
unsigned int p1;
if (fsocket == INVALID_SOCKET)
return false;
sockaddr_in sendmail;
sendmail.sin_family = AF_INET;
sendmail.sin_addr.s_addr = inet_addr ( "220.181.12.16" );
sendmail.sin_port = htons (25);
if ( connect (fsocket,(SOCKADDR*)&sendmail,sizeof(sendmail) ) == SOCKET_ERROR )
{
WSACleanup();
return false;
}
//////////////////////////////
recv(fsocket,strrecv,499,0);//连结后先会有一个响应
strcpy(strsend,"HELO smtp.163.com\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
strcpy(strsend,"AUTH LOGIN\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
encode64(MailUserName,strlen(MailUserName),strsend,255,&p1);
strcat(strsend,"\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
encode64(MailUserPass,strlen(MailUserPass),strsend,255,&p1);
strcat(strsend,"\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
strcpy(strsend,"MAIL FROM:<");
strcat(strsend,MailUserName);
strcat(strsend,"@163.com>\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
strcpy(strsend,"RCPT TO:<");
strcat(strsend,ReceMail);
strcat(strsend,">\r\n");
send(fsocket,strsend, strlen(strsend),0);
recv(fsocket,strrecv,499,0);
send(fsocket,"DATA\r\n", strlen("DATA\r\n"),0);
recv(fsocket,strrecv,499,0);
strcat(strsend,Info);
strcat(strsend,"\r\n---------------------------------------\r\n");
strcat(strsend,"langouster@163.com QQ:185826531\r\n.\r\n\r\n");
send(fsocket,strsend,strlen(strsend),0);
recv(fsocket,strrecv,499,0);
send(fsocket,"QUIT\r\n",strlen("QUIT\r\n"),0);
recv(fsocket,strrecv,499,0);
WSACleanup();
return true;
}