用QQ来向其他邮箱发邮件时,若用SMTP,则会发送不成功。可参照http://www.cnblogs.com/chhuic/archive/2009/09/26/1574375.html随笔。经查找相关资料,原来是为了防止垃圾邮件的发送,邮件提供商都使用了ESMTP协议了,以下是采用ESMTP协议来达到QQ发送邮件的目的。
下面我把源代码贴出来,由于有比较详细的说明,在些不多解释了。

Code
1
NetworkStream ns = null;
2
string mailString = string.Empty;
3
4
/**//// <summary>
5
/// 发送邮件
6
/// </summary>
7
/// <param name="smtpServer">smtp服务器名或者IP</param>
8
/// <param name="port">smtp服务器开放的端口</param>
9
/// <param name="isEsmtp">是否需要验证</param>
10
/// <param name="userName">用户名</param>
11
/// <param name="userPwd">密码</param>
12
/// <param name="mail">邮件对象</param>
13
/// <returns></returns>
14
public bool SendMail(string smtpServer, int port, bool isEsmtp, string userName, string userPwd, Mail2 mail)
15
{
16
TcpClient client = new TcpClient();
17
IPAddress ip = Dns.GetHostAddresses(smtpServer)[0];
18
IPEndPoint remoteEP = new IPEndPoint(ip, port);
19
client.Connect(remoteEP);
20
if (client.Connected)
21
{
22
23
ns = client.GetStream();
24
if (GetStatusCode() != 220)
25
{
26
return false;
27
}
28
SendCmd("HELO " + smtpServer + "\r\n");
29
if (GetStatusCode() != 250)
30
{
31
return false;
32
}
33
if (isEsmtp)
34
{
35
SendCmd("AUTH LOGIN\r\n");
36
if (GetStatusCode() != 334)
37
{ return false; }
38
SendCmd(GetBase64String(userName) + "\r\n");
39
if (GetStatusCode() != 334)
40
{ return false; }
41
SendCmd(GetBase64String(userPwd) + "\r\n");
42
if (GetStatusCode() != 235)
43
{ return false; }
44
}
45
SendCmd("MAIL FROM: <" + mail.MailFrom + ">\r\n");//必须加个‘<’、‘>’,否则出现500 bad Syntax 错误,即命令语法错误
46
if (GetStatusCode() != 250)
47
{ return false; }
48
foreach (string to in mail.MailTo)
49
{
50
SendCmd("RCPT TO: <" + to + ">\r\n");//必须加个‘<’、‘>’,否则出现500 bad Syntax 错误,即命令语法错误
51
if (GetStatusCode() != 250)
52
{ return false; }
53
}
54
SendCmd("data\r\n");
55
if (GetStatusCode() != 354)
56
{ return false; }
57
StringBuilder content = new StringBuilder();
58
59
content.AppendFormat("From:{0}\r\n", mail.MailFrom);
60
string toTxt = string.Empty;
61
foreach (string to in mail.MailTo)
62
{
63
toTxt += to + ";";
64
}
65
toTxt = toTxt.Substring(0, toTxt.Length - 1);
66
content.AppendFormat("To:{0}\r\n", toTxt);//发送到达邮件
67
content.AppendFormat("Date:{0}\r\n", mail.SendDate.ToString());//发送时间
68
content.AppendFormat("Subject:{0}\r\n", mail.Subject);//邮件主题
69
content.Append("\r\n");
70
content.Append(mail.Content);//邮件内容
71
content.Append("\r\n.\r\n");
72
SendCmd(content.ToString());
73
if (GetStatusCode() != 250)//250 表示命令执行成功
74
{
75
return false;
76
77
}
78
else
79
{
80
return true;
81
}
82
}
83
else
84
{
85
return false;
86
}
87
}
88
/**//// <summary>
89
/// 发送邮件命令
90
/// </summary>
91
/// <param name="cmd">命令</param>
92
private void SendCmd(string cmd)
93
{
94
byte[] data = Encoding.UTF8.GetBytes(cmd);
95
ns.Write(data, 0, data.Length);
96
ns.Flush();//提交
97
}
98
/**//// <summary>
99
/// 得到发送邮件命令状态
100
/// </summary>
101
/// <returns></returns>
102
private int GetStatusCode()
103
{
104
byte[] data = new byte[1024];
105
int i = ns.Read(data, 0, data.Length);
106
string str = Encoding.UTF8.GetString(data, 0, i);//获取返回命令字符串
107
if (str.Length > 3)
108
{
109
str = str.Substring(0, 3);
110
}//得到命令标识,由三位数字来表示,具体含义可参考ESMTP相关文档
111
int code = 0;
112
try
113
{
114
code = int.Parse(str);
115
}
116
catch
{ }
117
return code;
118
}
119
/**//// <summary>
120
/// BASE64 加密
121
/// </summary>
122
/// <param name="source"></param>
123
/// <returns></returns>
124
private string GetBase64String(string source)
125
{
126
byte[] data = Encoding.UTF8.GetBytes(source);
127
return Convert.ToBase64String(data);
128
}
以下是测试用例:
163邮箱向QQ邮箱发送

QQ邮箱向163邮箱发送

QQ向163发送成功界面:

QQ向163发过程:
下面我把源代码贴出来,由于有比较详细的说明,在些不多解释了。


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



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

52



53

54

55

56



57

58

59

60

61

62



63

64

65

66

67

68

69

70

71

72

73

74



75

76

77

78

79



80

81

82

83

84



85

86

87

88


89

90

91

92

93



94

95

96

97

98


99

100

101

102

103



104

105

106

107

108



109

110

111

112

113



114

115

116



117

118

119


120

121

122

123

124

125



126

127

128

以下是测试用例:
163邮箱向QQ邮箱发送

QQ邮箱向163邮箱发送

QQ向163发送成功界面:

QQ向163发过程:
IP:119.147.18.223
Port:25
begin connect .....
connected
220 Esmtp QQ Mail Server
HELO smtp.qq.com
250 Esmtp OK
AUTH LOGIN
334 VXNlcm5hbWU6
user:XXXXXXXXXXXX
334 XXXXXXXXXXXX
passXXXXXXXXXXXX=
235 Authentication successful
MAIL FROM: <123456@qq.com>
250 Ok
RCPT TO: <test@163.com>
250 Ok
data
354 End data with <CR><LF>.<CR><LF>
From:123456@qq.com
To:test@163.com
Date:0001-1-1 0:00:00
Subject:Subject
body text
.
250 Ok: queued as
========================================
2009年10月22日上传:
源代码打包下载:MailDemo(VS2008)