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 }
  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/javado/p/4451104.html
Copyright © 2011-2022 走看看