因此,我有一个用Java编写的客户端,我想用它来测试发送电子邮件,但不是使用像谷歌这样的现有SMTP,我想有自己的本地服务器来测试在两个模拟电子邮件之间发送模拟电子邮件。
我一直试图在互联网上寻找如何编写一个简单的SMTP服务器的好来源,但我没有运气。
我有一个基本的服务器代码,当我运行它,我可以连接我的客户端到它,但目前它不会处理任何电子邮件功能。
TCPServer.java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.*;
import java.net.*;
public class TCPServer{
private ServerSocket server;
/**
* The TCPServer constructor initiate the socket
* @param ipAddress
* @param port
* @throws Exception
*/
public TCPServer(String ipAddress, int port) throws Exception {
if (ipAddress != null && !ipAddress.isEmpty())
this.server = new ServerSocket(port, 1, InetAddress.getByName(ipAddress));
else
this.server = new ServerSocket(0, 1, InetAddress.getLocalHost());
}
/**
* The listen method listen to incoming client's datagrams and requests
* @throws Exception
*/
private void listen() throws Exception {
// listen to incoming client's requests via the ServerSocket
//add your code here
String data = null;
Socket client = this.server.accept();
String clientAddress = client.getInetAddress().getHostAddress();
System.out.println("\r\nNew client connection from " + clientAddress);
// print received datagrams from client
//add your code here
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while ( (data = in.readLine()) != null ) {
System.out.println("\r\nMessage from " + clientAddress + ": " + data);
client.sendUrgentData(1);
}
}
public InetAddress getSocketAddress() {
return this.server.getInetAddress();
}
public int getPort() {
return this.server.getLocalPort();
}
public static void main(String[] args) throws Exception {
// set the server address (IP) and port number
//add your code here
String serverIP = "192.168.1.235"; // local IP address
int port = 8088;
if (args.length > 0) {
serverIP = args[0];
port = Integer.parseInt(args[1]);
}
// call the constructor and pass the IP and port
//add your code here
TCPServer server = new TCPServer(serverIP, port);
System.out.println("\r\nRunning Server: " +
"Host=" + server.getSocketAddress().getHostAddress() +
" Port=" + server.getPort());
server.listen();
}
}
我可以添加什么到我现有的服务器代码,使它为我的客户端处理电子邮件。我也将张贴我的电子邮件客户端以及。
ClientTester.java
import java.io.*;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
/**
* This program demonstrates a TCP client
* @author jl922223
* @version 1.0
* @since 2020-12-12
*/
public class ClientTester{
private Socket tcpSocket;
private InetAddress serverAddress;
private int serverPort;
private Scanner scanner;
/**
* @param serverAddress
* @param serverPort
* @throws Exception
*/
private ClientTester(InetAddress serverAddress, int serverPort) throws Exception {
this.serverAddress = serverAddress;
this.serverPort = serverPort;
//Initiate the connection with the server using Socket.
//For this, creates a stream socket and connects it to the specified port number at the specified IP address.
//add your code here
this.tcpSocket = new Socket(this.serverAddress, this.serverPort);
this.scanner = new Scanner(System.in);
}
/**
* The start method connect to the server and datagrams
* @throws IOException
*/
/* private void start() throws IOException {
String input;
//create a new PrintWriter from an existing OutputStream (i.e., tcpSocket).
//This convenience constructor creates the necessary intermediateOutputStreamWriter, which will convert characters into bytes using the default character encoding
//You may add your code in a loop so that client can keep send datagrams to server
//add your code here
while (true) {
System.out.print ("C:");
input = scanner.nextLine();
PrintWriter output = new PrintWriter(this.tcpSocket.getOutputStream(), true);
output.println(input);
output.flush();
}
}*/
public static void main(String[] args) throws Exception {
// set the server address (IP) and port number
//add your code here
//IP: 192.168.1.235
//Port: 8088
InetAddress serverIP = InetAddress.getByName("smtp.google.com"); // local IP address
int port = 25;
if (args.length > 0) {
serverIP = InetAddress.getByName(args[0]);
port = Integer.parseInt(args[1]);
}
// call the constructor and pass the IP and port
//add your code here
ClientTester client = new ClientTester(serverIP, port);
// client.start();
try{
client = new ClientTester(serverIP, port);
System.out.println("\r\n Connected to Server: " + client.tcpSocket.getInetAddress());
BufferedReader stdin;
stdin = new BufferedReader (new InputStreamReader (System.in));
InputStream is = client.tcpSocket.getInputStream ();
BufferedReader sockin;
sockin = new BufferedReader (new InputStreamReader (is));
OutputStream os = client.tcpSocket.getOutputStream();
PrintWriter sockout;
sockout = new PrintWriter (os, true);
System.out.println ("S:" + sockin.readLine ());
while (true){
System.out.print ("C:");
String cmd = stdin.readLine ();
sockout.println (cmd);
String reply = sockin.readLine ();
System.out.println ("S:" + reply);
if (cmd.toLowerCase ().startsWith ("data") &&
reply.substring (0, 3).equals ("354"))
{
do
{
cmd = stdin.readLine ();
if (cmd != null && cmd.length () > 1 &&
cmd.charAt (0) == '.')
cmd = "."; // Must be no chars after . char.
sockout.println (cmd);
if (cmd.equals ("."))
break;
}
while (true);
// Read a reply string from the SMTP server program.
reply = sockin.readLine ();
// Display the first line of this reply string.
System.out.println ("S:" + reply);
continue;
}
// If the QUIT command was entered, quit.
if (cmd.toLowerCase ().startsWith ("quit"))
break;
}
}
catch (IOException e)
{
System.out.println (e.toString ());
}
finally
{
try
{
// Attempt to close the client socket.
if (client != null)
client.tcpSocket.close();
}
catch (IOException e)
{
}
}
}
}
好消息是,当我将ClientTester连接到smtp.google.com
时,它可以工作,但我不想使用Google,我想在java中拥有自己的基本电子邮件服务器。
3条答案
按热度按时间k75qkfdt1#
好的,找到了这个早期开发的独立版本。使用这个代替你的代码;单线程ServerSocket处理,因此一次只能处理一个连接。
你需要的唯一额外的文件(也包括在我之前的答案;编辑了一点):
iyr7buue2#
基本上就像我的代码。
read()
方法基本上是对套接字的InputStream的BufferedReader.readLine()
调用。handleSocket()
是建立Socket连接的时候。要知道这只是一个很容易被愚弄的愚蠢的实现,但是它可以实现基本的电子邮件接收。你在StringBuilder中获得所有的通信。你可以用MIME类(HTTP、SMTP等使用的Header / newline / newline body方法)将最终的整个文本分开。
这种方法首先收集整个通信,然后(在给定的代码之外)处理实际的MIME部分。你也可以用不同的方式实现它,因为代码知道当前传输的状态和它当前接收的MIME对象的细节,并在每一行更新它的状态/工作流。这将更有效,但代码会有点复杂。
查看此文件以了解一些端口和其他信息。
fumotvh33#
你需要和客户沟通。
首先让服务器向客户端发送类似于"220 SMTP服务器"(只有220事件)的内容。
我使用了PrintWriter:
然后,在从inputStream获取行的同时,您将从客户端接收到一个EHLO。
Here you can find an example of the communication between server an client (without the starting message from the server (220)): https://postmarkapp.com/guides/everything-you-need-to-know-about-smtp#basic-smtp-commands