c语言利用SMTP协议发送邮件

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 00:19   670   0

原文:http://apps.hi.baidu.com/share/detail/18176963


  1. #ifdef WIN32
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #else
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <errno.h>
  10. #include <unistd.h>
  11. #include <sys/time.h>
  12. #endif
  13. struct data6
  14. {
  15. unsigned int d4:6;
  16. unsigned int d3:6;
  17. unsigned int d2:6;
  18. unsigned int d1:6;
  19. };
  20. // 协议中加密部分使用的是base64方法
  21. char con628(char c6);
  22. void base64(char *dbuf,char *buf128,int len);
  23. void sendemail(char *email,char *body);
  24. int open_socket(struct sockaddr *addr);
  25. int main()
  26. {
  27. char email[] = "987654321@qq.com";
  28. char body[] = "From: \"lucy\"<123456789@qq.com>\r\n"
  29. "To: \"dasiy\"<987654321@qq.com>\r\n"
  30. "Subject: Hello\r\n\r\n"
  31. "Hello World, Hello Email!";
  32. sendemail(email, body);
  33. return 0;
  34. }
  35. char con628(char c6)
  36. {
  37. char rtn = '\0';
  38. if (c6 < 26) rtn = c6 + 65;
  39. else if (c6 < 52) rtn = c6 + 71;
  40. else if (c6 < 62) rtn = c6 - 4;
  41. else if (c6 == 62) rtn = 43;
  42. else rtn = 47;
  43. return rtn;
  44. }
  45. // base64的实现
  46. void base64(char *dbuf, char *buf128, int len)
  47. {
  48. struct data6 *ddd = NULL;
  49. int i = 0;
  50. char buf[256] = {0};
  51. char *tmp = NULL;
  52. char cc = '\0';
  53. memset(buf, 0, 256);
  54. strcpy(buf, buf128);
  55. for(i = 1; i <= len/3; i++)
  56. {
  57. tmp = buf+(i-1)*3;
  58. cc = tmp[2];
  59. tmp[2] = tmp[0];
  60. tmp[0] = cc;
  61. ddd = (struct data6 *)tmp;
  62. dbuf[(i-1)*4+0] = con628((unsigned int)ddd->d1);
  63. dbuf[(i-1)*4+1] = con628((unsigned int)ddd->d2);
  64. dbuf[(i-1)*4+2] = con628((unsigned int)ddd->d3);
  65. dbuf[(i-1)*4+3] = con628((unsigned int)ddd->d4);
  66. }
  67. if(len%3 == 1)
  68. {
  69. tmp = buf+(i-1)*3;
  70. cc = tmp[2];
  71. tmp[2] = tmp[0];
  72. tmp[0] = cc;
  73. ddd = (struct data6 *)tmp;
  74. dbuf[(i-1)*4+0] = con628((unsigned int)ddd->d1);
  75. dbuf[(i-1)*4+1] = con628((unsigned int)ddd->d2);
  76. dbuf[(i-1)*4+2] = '=';
  77. dbuf[(i-1)*4+3] = '=';
  78. }
  79. if(len%3 == 2)
  80. {
  81. tmp = buf+(i-1)*3;
  82. cc = tmp[2];
  83. tmp[2] = tmp[0];
  84. tmp[0] = cc;
  85. ddd = (struct data6 *)tmp;
  86. dbuf[(i-1)*4+0] = con628((unsigned int)ddd->d1);
  87. dbuf[(i-1)*4+1] = con628((unsigned int)ddd->d2);
  88. dbuf[(i-1)*4+2] = con628((unsigned int)ddd->d3);
  89. dbuf[(i-1)*4+3] = '=';
  90. }
  91. return;
  92. }
  93. // 发送邮件
  94. void sendemail(char *email, char *body)
  95. {
  96. int sockfd = 0;
  97. struct sockaddr_in their_addr = {0};
  98. char buf[1500] = {0};
  99. char rbuf[1500] = {0};
  100. char login[128] = {0};
  101. char pass[128] = {0};
  102. #ifdef WIN32
  103. WSADATA WSAData;
  104. WSAStartup(MAKEWORD(2, 2), &WSAData);
  105. #endif
  106. memset(&their_addr, 0, sizeof(their_addr));
  107. their_addr.sin_family = AF_INET;
  108. their_addr.sin_port = htons(25);
  109. their_addr.sin_addr.s_addr = inet_addr("112.90.141.71");//qq smtp 服务器
  110. // 连接邮件服务器,如果连接后没有响应,则2 秒后重新连接
  111. sockfd = open_socket((struct sockaddr *)&their_addr);
  112. memset(rbuf,0,1500);
  113. while(recv(sockfd, rbuf, 1500, 0) == 0)
  114. {
  115. printf("reconnect...\n");
  116. Sleep(2);
  117. //close(sockfd);
  118. sockfd = open_socket((struct sockaddr *)&their_addr);
  119. memset(rbuf,0,1500);
  120. }
  121. printf("%s\n", rbuf);
  122. // EHLO
  123. memset(buf, 0, 1500);
  124. sprintf(buf, "EHLO abcdefg-PC\r\n");
  125. send(sockfd, buf, strlen(buf), 0);
  126. memset(rbuf, 0, 1500);
  127. recv(sockfd, rbuf, 1500, 0);
  128. printf("%s\n", rbuf);
  129. // AUTH LOGIN
  130. memset(buf, 0, 1500);
  131. sprintf(buf, "AUTH LOGIN\r\n");
  132. send(sockfd, buf, strlen(buf), 0);
  133. printf("%s\n", buf);
  134. memset(rbuf, 0, 1500);
  135. recv(sockfd, rbuf, 1500, 0);
  136. printf("%s\n", rbuf);
  137. // USER
  138. memset(buf, 0, 1500);
  139. sprintf(buf,"12345678");//你的qq号
  140. memset(login, 0, 128);
  141. base64(login, buf, strlen(buf));
  142. sprintf(buf, "%s\r\n", login);
  143. send(sockfd, buf, strlen(buf), 0);
  144. printf("%s\n", buf);
  145. memset(rbuf, 0, 1500);
  146. recv(sockfd, rbuf, 1500, 0);
  147. printf("%s\n", rbuf);
  148. // PASSWORD
  149. sprintf(buf, "qqpassword");//你的qq密码
  150. memset(pass, 0, 128);
  151. base64(pass, buf, strlen(buf));
  152. sprintf(buf, "%s\r\n", pass);
  153. send(sockfd, buf, strlen(buf), 0);
  154. printf("%s\n", buf);
  155. memset(rbuf, 0, 1500);
  156. recv(sockfd, rbuf, 1500, 0);
  157. printf("%s\n", rbuf);
  158. // MAIL FROM
  159. memset(buf, 0, 1500);
  160. sprintf(buf, "MAIL FROM: <123456789@qq.com>\r\n");
  161. send(sockfd, buf, strlen(buf), 0);
  162. memset(rbuf, 0, 1500);
  163. recv(sockfd, rbuf, 1500, 0);
  164. printf("%s\n", rbuf);
  165. // RCPT TO 第一个收件人
  166. sprintf(buf, "RCPT TO:<%s>\r\n", email);
  167. send(sockfd, buf, strlen(buf), 0);
  168. memset(rbuf, 0, 1500);
  169. recv(sockfd, rbuf, 1500, 0);
  170. printf("%s\n", rbuf);
  171. // DATA 准备开始发送邮件内容
  172. sprintf(buf, "DATA\r\n");
  173. send(sockfd, buf, strlen(buf), 0);
  174. memset(rbuf, 0, 1500);
  175. recv(sockfd, rbuf, 1500, 0);
  176. printf("%s\n", rbuf);
  177. // 发送邮件内容,\r\n.\r\n内容结束标记
  178. sprintf(buf, "%s\r\n.\r\n", body);
  179. send(sockfd, buf, strlen(buf), 0);
  180. memset(rbuf, 0, 1500);
  181. recv(sockfd, rbuf, 1500, 0);
  182. printf("%s\n", rbuf);
  183. // QUIT
  184. sprintf(buf, "QUIT\r\n");
  185. send(sockfd, buf, strlen(buf), 0);
  186. memset(rbuf, 0, 1500);
  187. recv(sockfd, rbuf, 1500, 0);
  188. printf("%s\n", rbuf);
  189. // VC2005 需要使用
  190. closesocket(sockfd);
  191. // close(sockfd);
  192. #ifdef WIN32
  193. WSACleanup();
  194. #endif
  195. return;
  196. }
  197. // 打开TCP Socket连接
  198. int open_socket(struct sockaddr *addr)
  199. {
  200. int sockfd = 0;
  201. sockfd=socket(PF_INET, SOCK_STREAM, 0);
  202. if(sockfd < 0)
  203. {
  204. fprintf(stderr, "Open sockfd(TCP) error!\n");
  205. exit(-1);
  206. }
  207. if(connect(sockfd, addr, sizeof(struct sockaddr)) < 0)
  208. {
  209. fprintf(stderr, "Connect sockfd(TCP) error!\n");
  210. exit(-1);
  211. }
  212. return sockfd;
  213. }
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP