You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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 220 greeting when a client connects
  • Parse each incoming client command and return the correct SMTP response code
  • Handle the special DATA phase, 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 PrintWriter to send formatted SMTP responses back to the client
  • Implemented the initial 220 greeting on connection
  • Added command parsing for each SMTP command (HELLO, MAIL FROM, RCPT TO, DATA, QUIT)
  • Added special handling for the DATA phase, reading lines until a single . is received
  • Added cleanup for streams and sockets after the connection closes

Testing the Setup

  1. Run the modified TCPServer first
  2. Run your existing ClientTester
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:57:46