如何基于Java实现自定义SMTP服务器并集成至现有TCP服务,完成邮件客户端本地模拟测试
Adding SMTP Protocol Logic to Your TCP Server
Alright, let's fix this up. Your current TCP server can accept connections and read incoming messages, but it's missing the SMTP-specific response logic to match the flow you outlined. Here's how to modify your code to handle each step of the SMTP interaction:
Key Changes Needed
We need to:
- Send the initial
220greeting when a client connects - Parse each incoming client command and return the correct SMTP response code
- Handle the special
DATAphase, where we accept message content until we receive a single.on a line
Modified TCPServer Code
Here's the updated server code with full SMTP logic implemented:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; public class TCPServer { private ServerSocket server; 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()); } private void listen() throws Exception { Socket client = this.server.accept(); String clientAddress = client.getInetAddress().getHostAddress(); System.out.println("\r\nNew client connection from " + clientAddress); // Setup input/output streams for SMTP communication BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(client.getOutputStream(), true); String data; // Send initial SMTP greeting (required first step) out.println("220 " + server.getInetAddress().getHostAddress()); while ((data = in.readLine()) != null) { System.out.println("\r\nMessage from " + clientAddress + ": " + data); String command = data.trim().toUpperCase(); // Handle each SMTP command if (command.startsWith("HELLO")) { // Respond to HELO with 250 greeting out.println("250 Hello email1@email1.com, pleased to meet you"); } else if (command.startsWith("MAIL FROM:")) { // Validate MAIL FROM (basic check here; you can add more logic) out.println("250 ok"); } else if (command.startsWith("RCPT TO:")) { // Validate RCPT TO (basic check here) out.println("250 ok"); } else if (command.startsWith("DATA")) { // Enter data mode, prompt client to end with <CR><LF>.<CR><LF> out.println("354 End data with <CR><LF>.<CR><LF>"); // Read message lines until we get a single "." String line; while ((line = in.readLine()) != null) { System.out.println("Message content: " + line); if (line.trim().equals(".")) { out.println("250 ok Message accepted for delivery"); break; } } } else if (command.startsWith("QUIT")) { // Respond to QUIT and close connection out.println("221 " + server.getInetAddress().getHostAddress() + " closing connection"); break; } else { // Handle unknown commands (optional, but good practice) out.println("500 Command unrecognized"); } } // Cleanup resources in.close(); out.close(); client.close(); System.out.println("\r\nConnection closed with " + clientAddress); } public InetAddress getSocketAddress() { return this.server.getInetAddress(); } public int getPort() { return this.server.getLocalPort(); } public static void main(String[] args) throws Exception { String serverIP = "192.168.1.235"; int port = 8088; if (args.length > 0) { serverIP = args[0]; port = Integer.parseInt(args[1]); } TCPServer server = new TCPServer(serverIP, port); System.out.println("\r\nRunning Server: " + "Host=" + server.getSocketAddress().getHostAddress() + " Port=" + server.getPort()); server.listen(); } }
What's Changed?
- Added
PrintWriterto send formatted SMTP responses back to the client - Implemented the initial
220greeting on connection - Added command parsing for each SMTP command (
HELLO,MAIL FROM,RCPT TO,DATA,QUIT) - Added special handling for the
DATAphase, reading lines until a single.is received - Added cleanup for streams and sockets after the connection closes
Testing the Setup
- Run the modified
TCPServerfirst - Run your existing
ClientTester - You should see the exact interaction flow you outlined:
S: 220 192.168.1.235 C: HELLO 192.168.1.235 S: 250 Hello email1@email1.com, pleased to meet you ... (rest of the flow)
Your existing client code should work as-is since it's already following the SMTP command sequence.
内容的提问来源于stack exchange,提问作者Jimmy665566
相关产品推荐
相关产品推荐

