本文實例介紹了簡單E-mail發送端程序的Java實現代碼,分享給大家供大家參考,具體內容如下
在這個代碼中,有幾個注意點強調一下:
1、使用 Socket 與 SMTP 郵件服務器取得連接,注意 SMTP 服務器的主機名;
2、使用 data 命令時,若寫了 subject (主題)之后,郵件的正文部分必須與 subject 之間有一個空行,即“回車+換行”,在代碼中則是 \r\n ;
3、同樣需要將發件人的郵箱用戶名、密碼進行 BASE64 編碼之后再傳給 SMTP 服務器;
4、程序在編譯時仍然存在警告,這是由于 sun.misc.BASE64Encoder 類是存在于 rt.jar 包中的,由于 JDK 會更新升級,可能會導致該包中的某些類發生變化而不可用,所以編譯器會發出警告。
此外,寫了這些代碼,也發現了一些問題:
1、smtp.qq.com 和 smtp.sina.com 郵件服務器不知道為什么不能用,也就是說,當發件人的郵箱地址是 qq 或者 sina 時,這個程序不管用了,狀態應答碼也看不懂。在我的測試當中,只有 smtp.163.com 可以用,明明都是在官網查到這幾個 SMTP 服務器的,怎么不能用呢?真奇怪。有哪位朋友知道的希望能告訴我,謝謝!
2、在下面的 SimpleMailSender 類中的 sendEmail() 方法中,有些重復代碼讓人感到疑惑,但是沒辦法,我暫時還弄不懂…
3、重大發現:QQ 郵箱接收郵件的速度比 163 郵箱、sina 郵箱要快上可能有數十倍,真讓我驚訝。此外,使用 nslookup 命令查詢 smtp.qq.com 的主機名時,發現它有好多臺 SMTP 服務器,至少比 163 的 3 臺多出 5 臺,騰訊真夠強大;
4、雖然說寫了這個程序可以惡意地不停給某個郵箱發郵件,但是我發現,當我用一個 sina 郵箱連續發送了幾十封郵件給固定的另一個郵箱之后,該 sina 郵箱再想發郵件就會被拒絕,小心喲。
代碼如下:
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
// 郵件 class E_Mail { String from; String to; String subject; String content; String userName; String pwd; public E_Mail(String from, String to, String subject, String content, String userName, String pwd) { this .from = from; this .to = to; this .subject = subject; this .content = content; this .userName = this .toBASE64(userName); this .pwd = this .toBASE64(pwd); } /** * 在 E_Mail 類中進行用戶名、密碼的轉碼工作 */ private String toBASE64(String str) { return ( new sun.misc.BASE64Encoder().encode(str.getBytes())); } } // 簡單的郵件發送端類,實現發送功能 public class SimpleMailSender { private String smtpServer; private int port = 25 ; private Socket socket; BufferedReader br; PrintWriter pw; /** * 根據發件人的郵箱地址確定SMTP郵件服務器 */ private void initServer(String from) { if (from.contains( "@163" )) { this .smtpServer = "smtp.163.com" ; } else if (from.contains( "@126" )) { this .smtpServer = "smtp.126.com" ; } else if (from.contains( "@sina" )) { this .smtpServer = "smtp.sina.com" ; } else if (from.contains( "@qq" )) { this .smtpServer = "smtp.qq.com" ; } } public void sendEmail(E_Mail email) { try { this .initServer(email.from); this .socket = new Socket(smtpServer, port); this .br = this .getReader(socket); this .pw = this .getWriter(socket); // 開始組裝發送郵件的命令序列 send_Receive( null ); // 接收連接SMTP服務器成功的信息 send_Receive( "ehlo hao" ); send_Receive( "auth login" ); send_Receive(email.userName); send_Receive(email.pwd); send_Receive( "mail from:<" + email.from + ">" ); send_Receive( "rcpt to:<" + email.to + ">" ); send_Receive( "data" ); // 郵件內容 pw.println( "from:" + email.from); pw.println( "to:" + email.to); // 主題與正文之間一定要空一行,即加上"\r\n" pw.println( "subject:" + email.subject + "\r\n" ); // 在控制臺打印郵件內容 System.out.println( "from:" + email.from); System.out.println( "to:" + email.to); System.out.println( "subject:" + email.subject + "\r\n" ); System.out.println(email.content); // 郵件正文 pw.println(email.content); // 一定記得正文以"."結束 send_Receive( "." ); send_Receive( "quit" ); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null ) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 每發送一條命令,必須在命令后面加上"\r\n", * 則同時打印出smtp郵件服務器的相應狀態碼 * @param command */ private void send_Receive(String command) throws IOException{ if (command != null ) { // 向SMTP郵件服務器發送命令,一定要記得加上"\r\n" pw.print(command + "\r\n" ); pw.flush(); System.out.println( "用戶 >> " + command); } char [] response = new char [ 1024 ]; br.read(response); System.out.println(response); } /** * 獲取 Socket 的輸出流 */ private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut, true ); } /** * 獲取 Socket 的輸入流 */ private BufferedReader getReader(Socket socket) throws IOException { InputStream socketIn = socket.getInputStream(); return new BufferedReader( new InputStreamReader(socketIn)); } // 測試 public static void main(String[] args) { new MailSenderGUI(); } } // 郵件發送程序界面 class MailSenderGUI extends JFrame implements ActionListener { private JLabel userNameLabel; private JTextField userNameField; private JLabel pwdLabel; private JPasswordField pwdField; private JLabel fromLabel; private JTextField fromField; private JLabel toLabel; private JTextField toField; private JLabel subjectLabel; private JTextField subjectField; private JLabel contentLabel; private JTextArea contentArea; private JButton sendBtn; private JButton cancelBtn; private E_Mail email; private SimpleMailSender mailSender; public MailSenderGUI() { this .init(); this .mailSender = new SimpleMailSender(); } private void init() { this .fromLabel = new JLabel( "發件人郵箱地址:" ); this .fromField = new JTextField( 25 ); this .userNameLabel = new JLabel( "用戶名:" ); this .userNameField = new JTextField( 25 ); this .pwdLabel = new JLabel( "密碼:" ); this .pwdField = new JPasswordField( 25 ); this .toLabel = new JLabel( "收件人郵箱地址:" ); this .toField = new JTextField( 25 ); this .subjectLabel = new JLabel( "郵件主題:" ); this .subjectField = new JTextField( 20 ); this .contentLabel = new JLabel( "郵件正文:" ); this .contentArea = new JTextArea( 15 , 20 ); this .setTitle( "螞蟻-->簡單郵件發送器" ); this .setBounds( 200 , 30 , 500 , 500 ); this .setLayout( new BorderLayout()); this .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this .setVisible( true ); this .sendBtn = new JButton( "發送" ); this .cancelBtn = new JButton( "重置" ); this .sendBtn.addActionListener( this ); this .cancelBtn.addActionListener( this ); JPanel upPanel = new JPanel( new GridLayout( 6 , 2 , 5 , 5 )); upPanel.add(fromLabel); upPanel.add(fromField); upPanel.add(userNameLabel); upPanel.add(userNameField); upPanel.add(pwdLabel); upPanel.add(pwdField); upPanel.add(toLabel); upPanel.add(toField); upPanel.add(subjectLabel); upPanel.add(subjectField); upPanel.add(contentLabel); this .add(upPanel, BorderLayout.NORTH); this .add(contentArea, BorderLayout.CENTER); JPanel downPanel = new JPanel( new FlowLayout(FlowLayout.CENTER)); downPanel.add(sendBtn, BorderLayout.SOUTH); downPanel.add(cancelBtn, BorderLayout.SOUTH); this .add(downPanel, BorderLayout.SOUTH); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == this .sendBtn) { this .email = new E_Mail( this .fromField.getText(), this .toField.getText(), this .subjectField.getText(), this .contentArea.getText(), this .userNameField.getText(), new String( this .pwdField.getPassword()) ); this .mailSender.sendEmail( this .email); } else if (e.getSource() == this .cancelBtn) { this .fromField.setText( null ); this .toField.setText( null ); this .subjectField.setText( null ); this .contentArea.setText( null ); } } } |
以上就是java編寫簡單E-mail發送端程序的全部代碼,希望對大家的學習有所幫助。