zoukankan      html  css  js  c++  java
  • c发邮件

      1 /* base64编码 */
      2 static const char* base64_enc_map = 
      3                                     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      4 int base64_encode( char* dst, size_t* dlen, const unsigned char* src, size_t slen )
      5 {
      6     size_t i, n;
      7     int C1, C2, C3;
      8     char* p;
      9 
     10     if ( slen == 0 )
     11     {
     12         return 0;
     13     }
     14 
     15     n = ( slen << 3 ) / 6;
     16 
     17     switch ( ( slen << 3 ) - ( n * 6 ) )
     18     {
     19         case  2:
     20             n += 3;
     21             break;
     22         case  4:
     23             n += 2;
     24             break;
     25         default:
     26             break;
     27     }
     28 
     29     if ( *dlen < n + 1 )
     30     {
     31         *dlen = n + 1;
     32         return -1;
     33     }
     34 
     35     n = ( slen / 3 ) * 3;
     36     for ( i = 0, p = dst; i < n; i += 3 )
     37     {
     38         C1 = *src++;
     39         C2 = *src++;
     40         C3 = *src++;
     41         *p++ = base64_enc_map[( C1 >> 2 ) & 0x3F];
     42         *p++ = base64_enc_map[( ( ( C1 &  3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F];
     43         *p++ = base64_enc_map[( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F];
     44         *p++ = base64_enc_map[C3 & 0x3F];
     45     }
     46 
     47     if ( i < slen )
     48     {
     49         C1 = *src++;
     50         C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
     51         *p++ = base64_enc_map[( C1 >> 2 ) & 0x3F];
     52         *p++ = base64_enc_map[( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F];
     53         ( i + 1 ) < slen ? ( *p++ = base64_enc_map[( ( C2 & 15 ) << 2 ) & 0x3F] ) : ( *p++ = '=' );
     54         *p++ = '=';
     55     }
     56 
     57     *dlen = p - dst;
     58     *p = 0;
     59 
     60     return 0;
     61 }
     62 
     63 /* 主动连接 */
     64 static SOCKET tcp_connect( const char* host, unsigned short port = 25, int msec = 100 )
     65 {
     66     int ret;
     67     SOCKET fd;
     68     struct sockaddr_in sin;
     69     struct hostent* h;
     70     unsigned long ul;
     71     struct timeval tv;
     72     struct linger lg;
     73     int nodelay;
     74     fd_set fdset;
     75 
     76     /* 填充服务器地址 */
     77     memset( &sin, 0, sizeof( sin ) );
     78     sin.sin_family = AF_INET;
     79     if ( ( h = gethostbyname( host ) ) == NULL || h->h_addrtype != AF_INET )
     80     {
     81         return INVALID_SOCKET;
     82     }
     83     memcpy( &sin.sin_addr.S_un.S_addr, h->h_addr, h->h_length );
     84     sin.sin_port = htons( port );
     85 
     86 
     87     /* 建socket */
     88     if ( ( fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) ==  INVALID_SOCKET )
     89     {
     90         return INVALID_SOCKET;
     91     }
     92 
     93     /* 设置非阻塞 */
     94     ul = 1;
     95     if ( ioctlsocket( fd, FIONBIO, &ul ) != 0 )
     96     {
     97         closesocket( fd );
     98         return INVALID_SOCKET;
     99     }
    100 
    101     /* 主动连接 */
    102     if ( connect( fd, ( const struct sockaddr* ) &sin, sizeof( sin ) ) != 0 )
    103     {
    104         FD_ZERO( &fdset );
    105         FD_SET( fd, &fdset );
    106 
    107         memset( &tv, 0, sizeof( tv ) );
    108         tv.tv_sec = msec / 1000;
    109         tv.tv_usec = ( msec % 1000 ) * 1000;
    110 
    111         /* 超时或报错 */
    112         if ( select( fd + 1, 0, &fdset, 0, &tv ) != 1 )
    113         {
    114             closesocket( fd );
    115             return INVALID_SOCKET;
    116         }
    117     }
    118 
    119     /* 置为阻塞 */
    120     ul = 0;
    121     ret = ioctlsocket( fd, FIONBIO, &ul );
    122     assert( ret == 0 );
    123 
    124     /*消除滞留*/
    125     memset( &lg, 0, sizeof( lg ) );
    126     ret = setsockopt( fd, SOL_SOCKET, SO_LINGER, ( const char* ) &lg, sizeof( lg ) );
    127     assert( ret == 0 );
    128 
    129     /*禁用合并*/
    130     nodelay = 1;
    131     ret = setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, ( const char* ) &nodelay, sizeof( nodelay ) );
    132     assert( ret == 0 );
    133 
    134     return fd;
    135 }
    136 
    137 
    138 #define RECV(fd, buff, suc) do { 
    139         if (recv( (fd), (buff), sizeof( (buff) ), 0 ) <= 0 || 
    140                 memcmp((buff), (suc), 3)) 
    141         { 
    142             closesocket((fd)); 
    143             return -1; 
    144         } 
    145     }while(0)
    146 
    147 
    148 #define SEND(fd, buff, len) do { 
    149         register size_t i = (len); 
    150         if (send( (fd), (buff), i, 0 ) < (int)i) 
    151         { 
    152             closesocket((fd)); 
    153             return -1; 
    154         } 
    155     }while(0)
    156 
    157 
    158 /* 发邮件 */
    159 int send_mail( const char* server,
    160                const char* user, const char* pwd, 
    161                const char* sender, const char* receiver, 
    162                const char* str, const unsigned char* data, size_t datalen )
    163 {
    164     SOCKET fd;
    165     char buff[1024];
    166     size_t len;
    167     size_t pos;
    168 
    169     /* 连接SMTP服务器 */
    170     fd = tcp_connect( server );
    171     if ( fd == INVALID_SOCKET )
    172     {
    173         ::MessageBox( NULL, "无法连接服务器,请检查网络设备!", "错误", MB_OK );
    174         return -1;
    175     }
    176 
    177     /* 邮件问答 */
    178     RECV( fd, buff, "220" );
    179 
    180     sprintf( buff, "HELO %s
    ", server );
    181     SEND( fd, buff, strlen( buff ) );
    182     RECV( fd, buff, "250" );
    183 
    184     /* 登录过程 */
    185     SEND( fd, "AUTH LOGIN
    ", 12 ); /* 请求登录 */
    186     RECV( fd, buff, "334" );
    187 
    188     len = sizeof( buff );
    189     base64_encode( buff, &len, ( const unsigned char* )user, strlen( user ) );
    190     strcat( buff, "
    " );
    191     SEND( fd, buff, len + 2 ); /* 用户名 */
    192     RECV( fd, buff, "334" );
    193 
    194     len = sizeof( buff );
    195     base64_encode( buff, &len, ( const unsigned char* )pwd, strlen( pwd ) );
    196     strcat( buff, "
    " );
    197     SEND( fd, buff, len + 2 ); /* 密码 */
    198     RECV( fd, buff, "235" );
    199 
    200     /* 邮件头 */
    201     sprintf( buff, "MAIL FROM:<%s>
    ", sender );
    202     SEND( fd, buff, strlen( buff ) ); /* 发送者 */
    203     RECV( fd, buff, "250" ); /* 250 Ok... */
    204 
    205     sprintf( buff, "RCPT TO:<%s>
    ", receiver );
    206     SEND( fd, buff, strlen( buff ) ); /* 接收者 */
    207     RECV( fd, buff, "250" );
    208 
    209     SEND( fd, "DATA
    ", 6 ); /* 请求发送数据 */
    210     RECV( fd, buff, "354" );
    211 
    212     sprintf( buff, "From:"javadotest"<%s>
    "
    213              "To:"javado"<%s>
    "
    214              "Subject:邮件标题
    "
    215              "MIME-Version: 1.0
    "
    216              "Content-Type: multipart/mixed; boundary="o0o0o0o0o"
    
    ", 
    217              sender, receiver );
    218     SEND( fd, buff, strlen( buff ) );
    219 
    220 
    221     /* 发送邮件内容 */
    222     sprintf( buff, "--o0o0o0o0o
    "
    223              "Content-Type: text/plain; charset="gb2312"
    
    "
    224              "%s
    
    ", str );
    225     SEND( fd, buff, strlen( buff ) );
    226 
    227 
    228 
    229 
    230     /* 发送附件 */
    231     strcpy( buff, "--o0o0o0o0o
    "
    232             "Content-Type: application/octet-stream; name="附件.doc"
    "
    233             "Content-Transfer-Encoding: base64
    "
    234             "Content-Disposition: attachment; filename="附件.doc"
    
    " );
    235     SEND( fd, buff, strlen( buff ) );
    236     if ( datalen > 0 )
    237     {
    238         for ( pos = 0; pos < datalen; )
    239         {
    240             len = sizeof( buff );
    241             memset( buff, 0, sizeof( buff ) );
    242 
    243             if ( datalen - pos >= 765 )
    244             {
    245                 base64_encode( buff, &len, data + pos, 765 );
    246                 strcat( buff, "
    " );
    247                 SEND( fd, buff, 1022 );
    248                 pos += 765;
    249             }
    250             else
    251             {
    252                 base64_encode( buff, &len, data + pos, datalen - pos );
    253                 strcat( buff, "
    " );
    254                 SEND( fd, buff, strlen( buff ) );
    255                 break;
    256             }
    257         }
    258     }
    259 
    260 
    261 
    262     /* 完成发送 */
    263     SEND( fd, "--o0o0o0o0o--
    .
    QUIT
    ", 24 ); /* 请求退出 */
    264     RECV( fd, buff, "250" ); /* 250 Ok */
    265 
    266     closesocket( fd );
    267     return 0;
    268 }
  • 相关阅读:
    C++ Boost 函数与回调应用
    C++ Boost库 操作字符串与正则
    C++ Boost库 实现命令行解析
    PHP 开发与代码审计(总结)
    c strncpy函数代码实现
    c strcat函数代码实现
    c strcpy函数代码实现
    c strlen函数代码实现
    Java-IO流-打印流
    Java-IO流-文件复制2
  • 原文地址:https://www.cnblogs.com/javado/p/4451104.html
Copyright © 2011-2022 走看看