一、设计题目
5、电子邮件客户端程序设计与实现
二、设计内容
设计一个电子邮件客户端程序。
三、设计步骤
3.1原理分析
一个电子邮件系统由三部分组成:用户代理、邮件服务器,以及邮件发送协议(如SMTP)和邮件接收协议(如POP3)。
3.2编程设计
案例的设计步骤:
- 课本知识点分析
- 相关步骤分析
- 代码设计
数据结构
关键代码
查看邮箱:
sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象
const char *host_id = "pop3.126.com";
pHostent = gethostbyname("pop.qq.com");
int port = 110;
addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(port); //连接端口110
发送邮箱:
sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象
pHostent = gethostbyname("smtp.qq.com"); //得到有关于域名的信息,链接到qq邮箱服务器
addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(25); //连接端口25
发送base64加密的账号与授权码
message = "MTkxMzM5NDg5OQ==\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
message = "cmdhbXdwc3libHdmZ2phag==\r\n";/**/
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
程序流程图
5,Email
四、调试过程
难点主要是base64加密,不过借助在线解码编码工具,得到解决。
五、结果及分析、
查看邮件,程序运行情况: 查看结果,已加密:
邮件代理上的结果:
结果一致。
发送邮件,程序运行情况(注:自己发给自己): 邮件代理上:
顺利接收应用程序发出的信息。
六、心得体会、
把程序设计运用到实际生活中,让程序不只是电脑里运行的、锻炼头脑的代码块,而是可以实实在在作用于现实、带来新的可能的有力工具。
#include <iostream>
#include <string>
#include <WinSock2.h>
#include <stdio.h>
#include <unistd.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib") /*链接ws2_32.lib动态链接库*/
int main()
{
char buff[50000]; //收到recv函数返回的结果
string message;
string info;
string subject;
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 1);
//WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令
int err = WSAStartup(wVersionRequested, &wsaData);
SOCKADDR_IN addrServer; //服务端地址
HOSTENT *pHostent;//hostent是host entry的缩写,该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表
SOCKET sockClient; //客户端的套接字
/*
使用 MAIL 命令指定发送者
使用 RCPT 命令指定接收者,可以重复使用RCPT指定多个接收者
*/
cout << "你想查看邮件还是发邮件?\n\t1.查看邮箱\n\t2.发送邮件\n";
int call;
cin >> call;
if (call == 2)
{
sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象
pHostent = gethostbyname("smtp.qq.com"); //得到有关于域名的信息,链接到qq邮箱服务器
addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(25); //连接端口25
//int connect (SOCKET s , const struct sockaddr FAR *name , int namelen ); //函数原型
err = connect(sockClient, (SOCKADDR *) &addrServer, sizeof(SOCKADDR)); //向服务器发送请求
buff[recv(sockClient, buff, 500, 0)] = '\0';
/*
登录邮件服务器
*/
message = "ehlo qq.com\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送ehlo命令
buff[recv(sockClient, buff, 500, 0)] = '\0'; //接收返回值
// cout <<"1" << buff << endl;
message = "auth login\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
// cout <<"2" << buff << endl;
/*
发送base64加密的用户名、密码
*/
message = "MTkxMzM5NDg5OQ==\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
// cout <<"3" << buff << endl;
message = "cmdhbXdwc3libHdmZ2phag==\r\n";/**/
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
// cout <<"4" << buff << endl;
string mail;
cout << "请输入收件人邮箱:";
cin >> mail;
//925541107@qq.com
message = "MAIL FROM:<1913394899@qq.com> \r\nRCPT TO:<";
message.append(mail);
message.append("> \r\n");
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
cout <<"5" << buff << endl;
buff[recv(sockClient, buff, 500, 0)] = '\0';
/*
使用 DATA 命令告诉服务器要发送邮件内容
*/
message = "DATA\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
// cout <<"6" << buff << endl;
message = "From: 1913394899@qq.com\r\nTo: " + mail + "\r\nsubject:";
cout << "主题:";
cin >> subject;
message.append(subject);
message.append("\r\n\r\n");
cout << "内容:";
cin >> info;
message.append(info);
message.append("\r\n.\r\n");
send(sockClient, message.c_str(), message.length(), 0);
// cout <<"7" << buff << endl;
message = "QUIT\r\n";
send(sockClient, message.c_str(), message.length(), 0);
buff[recv(sockClient, buff, 500, 0)] = '\0';
// cout <<"8" << buff << endl;
cout << "发送成功!" << endl;
//system("pause");
}
if (call == 1)
{
sockClient = socket(AF_INET, SOCK_STREAM, 0); //建立socket对象
const char *host_id = "pop3.126.com";
pHostent = gethostbyname("pop.qq.com");
int port = 110;
addrServer.sin_addr.S_un.S_addr = *((DWORD *) pHostent->h_addr_list[0]); //得到smtp服务器的网络字节序的ip地址
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(port); //连接端口110
err = connect(sockClient, (SOCKADDR *) &addrServer, sizeof(SOCKADDR)); //向服务器发送请求
buff[recv(sockClient, buff, 500, 0)] = '\0';
message = "user 1913394899@qq.com\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送账号
buff[recv(sockClient, buff, 500, 0)] = '\0'; //接收返回值
// std::cout << "Client : send name \nServer:"
// << buff << std::endl;
message = "pass rgamwpsyblwfgjaj\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送授权码
buff[recv(sockClient, buff, 500, 0)] = '\0'; //接收返回值
//std::cout << "Client : send pass \nServer:"
// << buff << std::endl;
message = "stat\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送状态
buff[recv(sockClient, buff, 500, 0)] = '\0'; //接收返回值
// sleep(1);
//std::cout << "Client : send stat \nServer : "
// << buff << std::endl;
message = "list\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送状态
buff[recv(sockClient, buff, 50000, 0)] = '\0'; //接收返回值
// sleep(1);
std::cout << "Client : send list \nServer :"
<< buff << std::endl;
while(1)
{
int n;
std::cout << "你先想查看那一封邮件?输入序号"
<< std::endl;
cin >> n;
message = "retr " + to_string(n) + "\r\n";
send(sockClient, message.c_str(), message.length(), 0); //发送状态
// sleep(1);
std::cout << "Client : send retr (...) \n";
buff[recv(sockClient, buff, 50000, 0)] = '\0'; //接收返回值
std::cout << "Server :" << buff << std::endl;
}
//下面的while循环有些问题,目前还没有想到解决方法。以后改正!
// while(1)
// {
/*int num = sock.recv_socket();
std::cout << "Server :" << sock.get_recvbuf() << std::endl;*/
/* if(num <= 0)
{
break;
}*/
// }
/* sock.send_socket("quit\r\n");
std::cout << "Client : send quit \nServer :"
<< sock.get_recvbuf() << std::endl;}*/
}
}