使用SMTP協議發郵件,通過測試163能夠正常使用,其餘郵箱可能沒法正常使用。開發環境:Windows XP 32 + VS2005windows
代碼以下:socket
#include <winsock2.h> #pragma comment( lib, "ws2_32.lib" ) #include <stdio.h> #include <conio.h> #include <windows.h> #include <string> using namespace std; #pragma warning( disable : 4996 ) #define RECIVER "你的郵箱@163.com" #define ACCOUNT "你的郵箱帳號" #define PASSWORD "你的郵箱密碼" #define SMTP_SERVER "smtp.163.com" #define SMTP_PORT 25 #define SENDER RECIVER #define TITLE "test_smtp_mail" #define MAIL_END "\r\n.\r\n" const char BASE_CODE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int Base64Encode( char* src, int src_len, char* dst ) { int dst_len = 0; while(src_len > 0) { *dst++ = BASE_CODE[(src[0] >> 2 ) & 0x3F]; if(src_len > 2) { *dst++ = BASE_CODE[((src[0] & 3) << 4) | (src[1] >> 4)]; *dst++ = BASE_CODE[((src[1] & 0xF) << 2) | (src[2] >> 6)]; *dst++ = BASE_CODE[src[2] & 0x3F]; } else { switch(src_len) { case 1: *dst ++ = BASE_CODE[(src[0] & 3) << 4 ]; *dst ++ = '='; *dst ++ = '='; break; case 2: *dst ++ = BASE_CODE[((src[0] & 3) << 4) | (src[1] >> 4)]; *dst ++ = BASE_CODE[((src[1] & 0x0F) << 2) | (src[2] >> 6)]; *dst ++ = '='; break; } } src += 3; src_len -= 3; dst_len +=4; } *dst = 0; return dst_len; } class Socket { public: Socket( const char* peer_name, int peer_port ) { HOSTENT* peer_host = gethostbyname( peer_name ); if( !peer_host ) { printf( "Socket:gethostbyname(%s) failed, error=%d!", peer_name, GetLastError() ); return; } sockaddr_in addr; memset( &addr, 0, sizeof( addr ) ); addr.sin_family = AF_INET; addr.sin_port = htons( peer_port ); addr.sin_addr = *(struct in_addr*)peer_host->h_addr; _sock = socket( PF_INET, SOCK_STREAM, 0 ); if( connect( _sock, ( const sockaddr* )&addr, sizeof( sockaddr ) ) != 0 ) { printf( "Socket:connect(%s %d) failed, error=%d!", peer_name, peer_port, GetLastError() ); closesocket( _sock ); return; } printf( "Connect %s %d\r\n", peer_name, peer_port ); } ~Socket() { closesocket( _sock ); } void Send( char* data, int data_len ) { send( _sock, data, data_len, 0 ); printf( "[Send] %s", data ); } void SendEx( char* format, ... ) { char data[1024]; int data_len = 1024; va_list vl; va_start( vl, format ); vsprintf( data, format, vl ); va_end( vl ); Send( data, ( int )strlen( data ) ); } int Recv( OUT char* data, int data_len ) { int recv_len = recv( _sock, data, data_len, 0 ); printf( "[Recv] %s", data ); return recv_len; } int TempRecv() { char data[1024]; int data_len = 1024; memset( data, 0, sizeof( char ) * 1024 ); return Recv( data, data_len ); } private: SOCKET _sock; }; class Mail { public: Mail( const char* sender, const char* reciver, const char* title, const char* content ) { _sender = sender; _reciver = reciver; _title = title; _content = content; } public: string _sender; string _reciver; string _title; string _content; }; class SMTPWrap { public: SMTPWrap() {} ~SMTPWrap() {} void SendMail( Mail& mail, const char* smtp_server, int smtp_port ) { Socket sock( smtp_server, smtp_port ); sock.TempRecv(); sock.SendEx( "EHLO %s\r\n", mail._sender.c_str() ); sock.TempRecv(); // login { sock.SendEx( "AUTH LOGIN\r\n" ); sock.TempRecv(); char buf[1024]; memset( buf, 0, sizeof( char ) * 1024 ); Base64Encode( ACCOUNT, ( int )strlen( ACCOUNT ), buf ); sock.SendEx( "%s\r\n", buf ); sock.TempRecv(); memset( buf, 0, sizeof( char ) * 1024 ); Base64Encode( PASSWORD, ( int )strlen( PASSWORD ), buf ); sock.SendEx( "%s\r\n", buf ); sock.TempRecv(); } // mail head { sock.SendEx( "MAIL FROM:<%s>\r\n", mail._sender.c_str() ); sock.TempRecv(); sock.SendEx( "RCPT TO:<%s>\r\n", mail._reciver.c_str() ); sock.TempRecv(); } // mail body { sock.SendEx( "DATA\r\nSubject:%s\r\nFrom:%s\r\nTo:%s\r\n\r\n%s%s", mail._title.c_str(), mail._sender.c_str(), mail._reciver.c_str(), mail._content.c_str(), MAIL_END ); } sock.SendEx( "QUIT\r\n" ); sock.TempRecv(); } }; void InitNet() { WSAData data; WSAStartup( MAKEWORD( 2, 2 ), &data ); } void ReleaseNet() { WSACleanup(); } void main() { InitNet(); Mail mail( SENDER, RECIVER, TITLE, "這是封測試郵件\r\nabcdefg1234567" ); SMTPWrap smtp; smtp.SendMail( mail, SMTP_SERVER, SMTP_PORT ); getch(); ReleaseNet(); }