c/c++ 实现邮件发送的功能

  1. 邮件发送功能的初步实现
  2. 需要加载 ws2_32.dll文件
#pragma comment (lib, "ws2_32.lib")  
  1. 参考相关结构体定义
 struct hostent
 {
  char *h_name;         //正式主机名
  char **h_aliases;     //主机别名
  int h_addrtype;       //主机IP地址类型:IPV4-AF_INET
  int h_length;  //主机IP地址字节长度,对于IPv4是四字节,即32位
  char **h_addr_list;   //主机的IP地址列表
 };
 #define h_addr h_addr_list[0]   //保存的是IP地址
struct sockaddr_in
{    
/*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/    
short sin_family;

/*Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/  
unsigned short sin_port;   

/*IP address in network byte order(Internet address)*/     
struct in_addr sin_addr;

/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
unsigned char sin_zero[8];
};
  1. 下面是代码部分
// email_new.cpp : 定义控制台应用程序的入口点。
//
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<winsock2.h>

#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
using namespace std;

// 连接服务器
SOCKET connect_server(char *host, int port);   // (swtp.163.com, 25)
// 断开连接
void disconnect(SOCKET c);

void send_msg(SOCKET c, char *msg);
void recv_msg(SOCKET c);
char* base64_encode(const char* data, int data_len);


const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

SOCKET connect_server(char *host, int port)
{
	WSADATA  wd;
	int ret = 0;
	SOCKET c;
	SOCKADDR_IN saddr;                       // ??结构体
	struct hostent *pHostent;

	ret = WSAStartup(MAKEWORD(2, 2), &wd);

	if (ret != 0)
	{
		return 0;
	}

	if (HIBYTE(wd.wVersion) != 2 || LOBYTE(wd.wVersion) != 2)
	{
		cout << "初始化失败" << endl;
		WSACleanup();
		return 1;
	}

	c = socket(AF_INET, SOCK_STREAM, 0);

	pHostent = gethostbyname(host);       //获取IP地址,解析

	saddr.sin_addr.S_un.S_addr = *((unsigned long*)pHostent->h_addr_list[0]);
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);

	connect(c, (SOCKADDR*)&saddr, sizeof(SOCKADDR));

	return c;
}

void disconnect(SOCKET c)
{
	closesocket(c);
	WSACleanup();
}

void recv_msg(SOCKET c)
{
	char text[BUFSIZ];
	strnset(text, '\0', BUFSIZ);
	recv(c, text, BUFSIZ, 0);
	cout << endl << "recv:" << text << endl;
}


void send_msg(SOCKET c, char *msg)
{
	cout << endl << "send:" << msg << endl;
	send(c, msg, strlen(msg), 0);
}


char *base64_encode(const char* data, int data_len)
{
	//int data_len = strlen(data); 
	int prepare = 0;
	int ret_len;
	int temp = 0;
	char *ret = NULL;
	char *f = NULL;
	int tmp = 0;
	char changed[4];
	int i = 0;
	ret_len = data_len / 3;
	temp = data_len % 3;
	if (temp > 0)
	{
		ret_len += 1;
	}
	ret_len = ret_len * 4 + 1;
	ret = (char *)malloc(ret_len);

	if (ret == NULL)
	{
		printf("No enough memory.\n");
		exit(0);
	}
	memset(ret, 0, ret_len);
	f = ret;
	while (tmp < data_len)
	{
		temp = 0;
		prepare = 0;
		memset(changed, '\0', 4);
		while (temp < 3)
		{
			//printf("tmp = %d\n", tmp); 
			if (tmp >= data_len)
			{
				break;
			}
			prepare = ((prepare << 8) | (data[tmp] & 0xFF));
			tmp++;
			temp++;
		}
		prepare = (prepare << ((3 - temp) * 8));
		//printf("before for : temp = %d, prepare = %d\n", temp, prepare); 
		for (i = 0; i < 4; i++)
		{
			if (temp < i)
			{
				changed[i] = 0x40;
			}
			else
			{
				changed[i] = (prepare >> ((3 - i) * 6)) & 0x3F;
			}
			*f = base[changed[i]];
			//printf("%.2X", changed[i]); 
			f++;
		}
	}
	*f = '\0';

	return ret;

}


int main(void)
{
	char sendbuf[BUFSIZ], recvbuf[BUFSIZ], recv_email[BUFSIZ], subject[BUFSIZ], content[BUFSIZ], email[200], pass[200];
	char *pstr = NULL;
	char *host = "smtp.163.com";
	int port = 25;
	SOCKET c;

	c = connect_server(host, port);

	recv_msg(c);   // 接收服务器的数据

	send_msg(c, "helo 163\r\n");   //跟服务器打招呼

	recv_msg(c);   // 接收服务器的数据

	send_msg(c, "auth login\r\n");   //告诉服务器要登陆

	recv_msg(c);   // 接收服务器的数据

	//提示用户输入邮箱地址
	cout << "---onload email---" << endl << "Address:";
	cin >> email;
	cout << "Password:";
	cin >> pass;

	//加密邮箱地址
	pstr = base64_encode(email, strlen(email));

	strcpy(sendbuf, pstr);
	strcat(sendbuf, "\r\n\0");  //加回车换行符号 ,\0字符串结束标志

	send_msg(c, sendbuf);

	recv_msg(c);   //接收返回内容并显示

	free(pstr);    //释放base64加密中分配的内存

	//加密邮箱密码
	pstr = base64_encode(pass, strlen(pass));

	strcpy(sendbuf, pstr);
	strcat(sendbuf, "\r\n\0");

	send_msg(c, sendbuf);

	recv_msg(c);

	free(pstr);   //释放base64加密中分配的内存

	//告诉服务器发件人是谁
	strcpy(sendbuf, "mail from:<");
	strcat(sendbuf, email);
	strcat(sendbuf, ">");
	strcat(sendbuf, "\r\n\0");
	send_msg(c, sendbuf);
	recv_msg(c);

	//告诉服务器收件人是谁
	cout << "destinate address:";
	cin >> recv_email;

	strcpy(sendbuf, "rcpt to:<");
	strcat(sendbuf, recv_email);
	strcat(sendbuf, ">");
	strcat(sendbuf, "\r\n\0");
	send_msg(c, sendbuf);
	recv_msg(c);

	//邮件内容
	send_msg(c, "data\r\n");
	recv_msg(c);

	cout << "title:";
	cin >> subject;     //cin遇见空格结束	
	cout << endl;
	cout << "content:";
	cin >> content;

	//选填发件人
	strcpy(sendbuf, "From: ");
	strcat(sendbuf, email);
	strcat(sendbuf, "\n");

	strcpy(sendbuf, "To: ");
	strcat(sendbuf, recv_email);
	strcat(sendbuf, "\n");
	
	//发送标题和内容
	strcat(sendbuf, "subject:");
	strcat(sendbuf, subject);
	strcat(sendbuf, "\r\n\r\n");
	strcat(sendbuf, content);
	strcat(sendbuf, "\r\n.\r\n\0");
	send_msg(c, sendbuf);
	recv_msg(c);

	disconnect(c);
	
	cout << "succeed arrive to:" << recv_email << endl;
	getchar();
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"C 发送邮件 QQ" 是指使用 C 语言编写程序来实现通过 QQ 邮箱发送邮件的功能。以下是一个简单的解释: QQ 邮箱是腾讯公司提供的一种电子邮件服务。要通过 C 语言发送 QQ 邮件,需要使用一些相关的库和协议来进行邮件发送和接收操作。 C 语言本身并不直接支持邮件发送功能,但可以利用第三方库来实现。一个常用的库是 libcurl,它是一个强大且广泛使用的网络传输库,可以用来发送 HTTP 请求。在 C 语言中,可以使用 libcurl 提供的接口来发送 HTTP 请求来执行发送邮件的操作。 首先,需要在 C 代码中包含 libcurl 的头文件,并链接对应的库文件。然后,通过初始化 libcurl 的函数来创建一个会话,设置相应的选项,如收件人、发件人、主题、正文内容等。接下来,使用 libcurl 提供的函数发送 HTTP POST 请求,将邮件内容以及相关的身份验证参数传递给 QQ 邮箱的服务器地址。最后,根据 QQ 邮箱服务器的响应,判断邮件发送是否成功,并进行相应的处理。 需要注意的是,发送邮箱是一个涉及到网络传输和身份验证的操作,需要保证网络连接的稳定性、合法的身份验证信息以及可信的邮件内容,以避免被视为垃圾邮件或滥用邮件发送功能。 综上所述,通过使用 C 语言编写包含 libcurl 库的程序,可以实现通过 QQ 邮箱发送邮件的功能。但这只是一个简单的示例,实际开发中需要考虑更多的细节和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值