用telnet来发邮件并用C语言实现

过程如下:

220 hz-b-126smtp1.126.com SMTP Server for Netease [466] e8241e55-7706-40c6-86bc-145
helo smtp.126.com
250 hz-b-126smtp1.126.com e8241e55-7706-40c6-86bc-14581e3c9753
auth login //登录
334 VXNlcm5hbWU6 e8241e55-7706-40c6-86bc-14581e3c9753
ZmVpZXI3NTAx   //这个是用base64编码的用户名
334 UGFzc3dvcmQ6 e8241e55-7706-40c6-86bc-14581e3c9753
xxxxxx  //这个是用base64编码的密码,我用xxxxxx来表示密码
235 OK, go ahead (#2.0.0) e8241e55-7706-40c6-86bc-14581e3c9753
mail from:<feier7501@126.com>
250 2.0.0 OK e8241e55-7706-40c6-86bc-14581e3c9753
rcpt to:<feier7501@126.com>
250 2.0.0 OK e8241e55-7706-40c6-86bc-14581e3c9753
data //开始输入邮件内容
354 Start mail input; end with <CRLF>.<CRLF> e8241e55-7706-40c6-86bc-14581e3c9753
from:<feier7501@126.com>
to:<feier7501@126.com>
subject:smtp test    //主题和正文之间要空一行

this is smtp test
. //用.和换行来表示结束
250 2.0.0 OK e8241e55-7706-40c6-86bc-14581e3c9753
quit //退出
221 2.0.0 Bye e8241e55-7706-40c6-86bc-14581e3c9753


失去了跟主机的连接。

C语言源代码如下:

base64.h:

/*  Copyright (c) 2006-2007, Philip Busch <broesel@studcs.uni-sb.de>
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * Base64 header.
 * @ingroup base64
 */

#ifndef _BASE64_H
#define _BASE64_H

void base64_encode_block(unsigned char out[4], const unsigned char in[3], int len);
int base64_decode_block(unsigned char out[3], const unsigned char in[4]);
size_t base64_encoded_size(size_t len);
size_t base64_decoded_size(size_t len);
void base64_encode_binary(char *out, const unsigned char *in, size_t len);
int base64_decode_binary(unsigned char *out, const char *in);
char *base64_encode(const char *in, size_t size);
char *base64_decode(const char *in);

#endif /* ! _BASE64_H */

base64.cpp:

/*  Copyright (c) 2006-2007, Philip Busch <broesel@studcs.uni-sb.de>
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 * Base64 implementation.
 * @ingroup base64
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "base64.h"

#define XX 100

/** @var base64_list
 *   A 64 character alphabet.
 *
 *   A 64-character subset of International Alphabet IA5, enabling
 *   6 bits to be represented per printable character.  (The proposed
 *   subset of characters is represented identically in IA5 and ASCII.)
 *   The character "=" signifies a special processing function used for
 *   padding within the printable encoding procedure.
 *
 *   \verbatim
 Value Encoding  Value Encoding  Value Encoding  Value Encoding
 0 A            17 R            34 i            51 z
 1 B            18 S            35 j            52 0
 2 C            19 T            36 k            53 1
 3 D            20 U            37 l            54 2
 4 E            21 V            38 m            55 3
 5 F            22 W            39 n            56 4
 6 G            23 X            40 o            57 5
 7 H            24 Y            41 p            58 6
 8 I            25 Z            42 q            59 7
 9 J            26 a            43 r            60 8
 10 K            27 b            44 s            61 9
 11 L            28 c            45 t            62 +
 12 M            29 d            46 u            63 /
 13 N            30 e            47 v
 14 O            31 f            48 w         (pad) =
 15 P            32 g            49 x
 16 Q            33 h            50 y
 \endverbatim
 */
static const char base64_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const int base64_index[256] = {
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, 62, XX, XX, XX, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, XX, XX, XX, XX, XX, XX,
XX, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, XX, XX, XX, XX, XX,
XX, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, };

/** Encode a minimal memory block. This function encodes a minimal memory area
 *  of three bytes into a printable base64-format sequence of four bytes.
 *  It is mainly used in more convenient functions, see below.
 *
 * @attention This function can't check if there's enough space at the memory
 *            memory location pointed to by \c out, so be careful.
 *
 * @param out pointer to destination
 * @param in pointer to source
 * @param len input size in bytes (between 0 and 3)
 * @returns nothing
 *
 * @ingroup base64
 */
void base64_encode_block(unsigned char out[4], const unsigned char in[3], int len) {
	out[0] = base64_list[in[0] >> 2];
	out[1] = base64_list[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
	out[2] = (unsigned char) (
			len > 1 ? base64_list[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '=');
	out[3] = (unsigned char) (len > 2 ? base64_list[in[2] & 0x3f] : '=');
}

/** Decode a minimal memory block. This function decodes a minimal memory area
 *  of four bytes into its decoded equivalent. It is mainly used in more
 *  convenient functions, see below.
 *
 * @attention This function can't check if there's enough space at the memory
 *            memory location pointed to by \c out, so be careful.
 *
 * @param out pointer to destination
 * @param in pointer to source
 * @returns -1 on error (illegal character) or the number of bytes decoded
 *
 * @ingroup base64
 */
int base64_decode_block(unsigned char out[3], const unsigned char in[4]) {
	int i, numbytes = 3;
	char tmp[4];

	for (i = 3; i >= 0; i--) {
		if (in[i] == '=') {
			tmp[i] = 0;
			numbytes = i - 1;
		} else {
			tmp[i] = base64_index[(unsigned char) in[i]];
		}

		if (tmp[i] == XX)
			return (-1);
	}

	out[0] = (unsigned char) (tmp[0] << 2 | tmp[1] >> 4);
	out[1] = (unsigned char) (tmp[1] << 4 | tmp[2] >> 2);
	out[2] = (unsigned char) (((tmp[2] << 6) & 0xc0) | tmp[3]);

	return (numbytes);
}

/** Compute size of needed storage for encoding. This function computes the
 *  \e exact size of a memory area needed to hold the result of an encoding
 *  operation, not including the terminating null character.
 *
 * @param len input size
 * @returns output size
 *
 * @ingroup base64
 */
size_t base64_encoded_size(size_t len) {
	return (((len + 2) / 3) * 4);
}

/** Compute size of needed storage for decoding. This function computes the
 *  \e estimated size of a memory area needed to hold the result of a decoding
 *  operation, not including the terminating null character. Note that this
 *  function may return up to two bytes more due to the nature of Base64.
 *
 * @param len input size
 * @returns output size
 *
 * @ingroup base64
 */
size_t base64_decoded_size(size_t len) {
	return ((len / 4) * 3);
}

/** Encode an arbitrary size memory area. This function encodes the first
 *  \c len bytes of the contents of the memory area pointed to by \c in and
 *  stores the result in the memory area pointed to by \c out. The result will
 *  be null-terminated.
 *
 * @attention This function can't check if there's enough space at the memory
 *            memory location pointed to by \c out, so be careful.
 *
 * @param out pointer to destination
 * @param in pointer to source
 * @param len input size in bytes
 * @returns nothing
 *
 * @ingroup base64
 */
void base64_encode_binary(char *out, const unsigned char *in, size_t len) {
	int size;
	size_t i = 0;

	while (i < len) {
		size = (len - i < 4) ? len - i : 4;

		base64_encode_block((unsigned char *) out, in, size);

		out += 4;
		in += 3;
		i += 3;
	}

	*out = '\0';
}

/** Decode an arbitrary size memory area. This function decodes the
 *  base64-string pointed to by \c in and stores the result in the memory area
 *  pointed to by \c out. The result will \e not be null-terminated.
 *
 * @attention This function can't check if there's enough space at the memory
 *            memory location pointed to by \c out, so be careful.
 *
 * @param out pointer to destination
 * @param in pointer to source
 * @returns -1 on error (illegal character) or the number of bytes decoded
 *
 * @ingroup base64
 */
int base64_decode_binary(unsigned char *out, const char *in) {
	size_t len = strlen(in), i = 0;
	int numbytes = 0;

	while (i < len) {
		if ((numbytes += base64_decode_block(out, (unsigned char *) in)) < 0)
			return (-1);

		out += 3;
		in += 4;
		i += 4;
	}

	return (numbytes);
}

/** Encode a string. This is a convenience function. It encodes the first
 *  \c size bytes of the string pointed to by \c in, stores the null-terminated
 *  result in a newly created memory area and returns a pointer to it.
 *
 * @attention After a call to base64_encode(), you have to free() the result
 *  yourself.
 *
 * @param in pointer to string
 * @param size strlen
 * @returns NULL on error (not enough memory) or a pointer to the encoded result
 *
 * @ingroup base64
 */
char *base64_encode(const char *in, size_t size) {
	char *out;
	size_t outlen;

	if (in == NULL)
		return (NULL);

	if (size == 0)
		size = strlen(in);

	outlen = base64_encoded_size(size);

	if ((out = (char *) malloc(sizeof(char) * (outlen + 1))) == NULL)
		return (NULL);

	base64_encode_binary(out, (unsigned char *) in, size);

	return (out);
}

/** Decode a string. This is a convenience function. It decodes the
 *  null-terminated string pointed to by \c in, stores the result in a newly
 *  created memory area and returns a pointer to it. The result will be
 *  null-terminated.
 *
 * @attention After a call to base64_decode(), you have to free() the result
 *  yourself.
 *
 * @param in pointer to string
 * @returns NULL on error (not enough memory) or a pointer to the decoded result
 *
 * @ingroup base64
 */
char *base64_decode(const char *in) {
	char *out;
	size_t outlen;
	int numbytes;

	outlen = base64_decoded_size(strlen(in));

	if ((out = (char *) malloc(sizeof(char) * (outlen + 1))) == NULL)
		return (NULL);

	if ((numbytes = base64_decode_binary((unsigned char *) out, in)) < 0) {
		free(out);
		return (NULL);
	}

	*(out + numbytes) = '\0';

	return (out);
}

email.cpp:

#include <io.h>
#include <WinSock2.h>
#include <stdio.h>
#include "base64.h"

#pragma comment(lib,"ws2_32.lib")

void sendmail_write(const int sock, const char *str, const char *arg) {
	char buf[1024];

	if (arg != NULL)
		sprintf(buf, str, arg);
	else
		sprintf(buf, str);

	send(sock, buf, strlen(buf), 0);
	printf("%s", buf);
}

void read_response(const int sock)
{
	char buf[1024]={0};

	recv(sock, buf, sizeof buf, 0);
	printf("%s", buf);
}

int sendmail(const char *from, const char *to, const char *subject, const char *body, const char *hostname, const int port, const char *b64User, const char *b64Pass) {
	struct hostent *host;
	struct sockaddr_in saddr_in;
	int sock = 0;

	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		return -1;
	}

	sock = socket(AF_INET, SOCK_STREAM, 0);
	host = gethostbyname(hostname);

	saddr_in.sin_family = AF_INET;
	saddr_in.sin_port = htons((u_short) port);
	saddr_in.sin_addr.s_addr = 0;

	memcpy((char*) &(saddr_in.sin_addr), host->h_addr, host->h_length);

	if (connect(sock, (struct sockaddr*) &saddr_in, sizeof(saddr_in)) == -1) {
		return -2;
	}

	sendmail_write(sock, "HELO %s\n", hostname);
	read_response(sock);
	sendmail_write(sock, "AUTH LOGIN\n", NULL);
	read_response(sock);
	sendmail_write(sock, "%s\n", b64User);
	read_response(sock);
	sendmail_write(sock, "%s\n", b64Pass);
	read_response(sock);
	sendmail_write(sock, "MAIL FROM:<%s>\n", from);
	read_response(sock);
	sendmail_write(sock, "RCPT TO:<%s>\n", to);
	read_response(sock);
	sendmail_write(sock, "DATA\n", NULL);    // begin data
	read_response(sock);

	sendmail_write(sock, "From:<%s>\n", from);
	sendmail_write(sock, "To:<%s>\n", to);
	sendmail_write(sock, "Subject:%s\n", subject);
	sendmail_write(sock, "\n", NULL);
	sendmail_write(sock, "%s\n", body);    // data
	sendmail_write(sock, ".\n", NULL);    // end data
	read_response(sock);
	sendmail_write(sock, "QUIT\n", NULL);    // terminate

	closesocket(sock);

	return 0;
}

int main(int argc, char *argv[]) {
	char user[25], pass[25];
	char *pB64user, *pB64pass;

	printf("Input username:\n");
	scanf("%s", user);
	printf("Input password:\n");
	scanf("%s", pass);

	pB64user = base64_encode(user, strlen(user));
	pB64pass = base64_encode(pass, strlen(pass));

	int ret = sendmail("feier7501@126.com", "feier7501@126.com", "sent by c", "using c", "smtp.126.com", 25, pB64user, pB64pass);

	if (ret != 0)
		fprintf(stderr, "Failed to send mail (code: %i).\n", ret);
	else
		fprintf(stdout, "Mail successfully sent.\n");

	return ret;
}


在VS2010里加入上面的代码,运行后,可以发送邮件,如果装了360,会出现警报。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值