testsmtp.cpp: // testsmtp.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <winsock.h> #include "base64.h" #pragma comment( lib,"ws2_32.lib" ) #define WSVERS MAKEWORD(2, 0) SOCKET connectTCP(const char *host, const char *service ); void errexit(const char *format, ...); FILE* pf_log; void ReveiveMsg(SOCKET sock, char* checkstr = "/r/n") { char buffer[1024]; fwrite("Server: ",1,strlen("Server: "),pf_log); while(1){ int len = recv(sock,buffer,1024,0); if (len <= 0) break; fwrite(buffer,1,len,pf_log); buffer[len] = 0; printf("Server: %s",buffer); //检测边界 if (strstr(buffer,checkstr)) break; } } void SendMsg(SOCKET sock,char* msg) { fwrite("Client: ",1,strlen("Client: "),pf_log); int msgLen = strlen(msg); send(sock,msg,msgLen,0); printf("Client: %s",msg); fwrite(msg,1,msgLen,pf_log); } int main(int argc, char* argv[]) { WSADATA wsadata; if (WSAStartup(WSVERS, &wsadata) != 0) errexit("WSAStartup failed/n"); pf_log = fopen("log.txt","wb"); // SOCKET sock = connectTCP("mail.hnu.cn","smtp"); SOCKET sock = connectTCP("smtp.163.com","smtp"); ReveiveMsg(sock); //服务器欢迎信息 SendMsg(sock,"EHLO 163.com/r/n"); //SMTP协议的握手信号 ReveiveMsg(sock,"250 8BITMIME/r/n"); SendMsg(sock,"AUTH LOGIN/r/n"); //开始认证登录 ReveiveMsg(sock); //准备好用户名的base64编码 int codelen; char username[]="ficefjb"; char *base64code; base64code = base64_encode(username,strlen(username)); codelen = strlen(base64code); char username_base64[256]; strcpy(username_base64,base64code); username_base64[codelen] = 0x0d; username_base64[codelen + 1] = 0x0a; username_base64[codelen + 2] = 0; SendMsg(sock,username_base64); //提交用户名 ReveiveMsg(sock); //准备好密码的base64编码 printf("Please input password:/n"); char password[256]; SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); scanf("%s",password); base64code = base64_encode(password,strlen(password)); codelen = strlen(base64code); char password_base64[256]; strcpy(password_base64,base64code); password_base64[codelen] = 0x0d; password_base64[codelen + 1] = 0x0a; password_base64[codelen + 2] = 0; SendMsg(sock,password_base64); //提交密码 ReveiveMsg(sock); //返回235表示成功 SendMsg(sock,"MAIL FROM:<ficefjb@163.com>/r/n"); //提交发送者 ReveiveMsg(sock); SendMsg(sock,"RCPT TO:<ficefjb@163.com>/r/n"); //提交接收者 ReveiveMsg(sock); SendMsg(sock,"DATA/r/n"); //通知服务器下面是邮件 ReveiveMsg(sock); //发送邮件头部信息 SendMsg(sock,"TO: ficefjb@163.com/r/nFROM: ficefjb@163.com/r/nSUBJECT: SMTP协议测试/r/nDate:2009-12-5/r/nX-Mailer:fice's mailer/r/n"); //邮件 SendMsg(sock,"MIMI-Version:1.0/r/n"); SendMsg(sock,"Content-Type:multipart/mixed;boundary=/"#BOUNDARY#/"/r/n/r/n"); //设置边界标识 SendMsg(sock,"Content-Transfer-Encoding:7bit/r/n/r/n"); SendMsg(sock,"This is a multi-part message in MIME format/r/n/r/n"); //发送邮件内容头部信息 SendMsg(sock,"--#BOUNDARY#/r/n"); SendMsg(sock,"Content-Type: text/plain;charset=gb2312/r/n"); SendMsg(sock,"Content-Transfer-Encoding:printable/r/n/r/n"); //发送邮件的内容部分 SendMsg(sock,"SMTP协议测试:发送附件/n----by fice 2009.12.5/r/n"); //发送附件头部信息 SendMsg(sock,"--#BOUNDARY#/r/n"); SendMsg(sock,"Content-Type:text/plain;name=student.txt/r/n"); SendMsg(sock,"Content-Transfer-Encoding:base64/r/n"); SendMsg(sock,"Content-Disposition:attachment;filename=/"student.txt/"/r/n/r/n"); //用二进制方式读取附件文件内容并转为base64格式 FILE* pf = fopen("d://student.txt","rb"); fseek(pf,0,SEEK_END); int filelen = ftell(pf); fseek(pf,0,SEEK_SET); char* filebuf = (char*) malloc(filelen); fread(filebuf,1,filelen,pf); char* filebase64 = base64_encode(filebuf,filelen); //发送邮件的附件部分 SendMsg(sock,filebase64); SendMsg(sock,"/r/n./r/n"); //邮件内容结束 ReveiveMsg(sock); SendMsg(sock,"QUIT/r/n"); //通知服务器退出 ReveiveMsg(sock); fclose(pf_log); closesocket(sock); WSACleanup(); printf("Press any key to quit./n"); getche(); return 0; }