首页 > 解决方案 > TcpListener 没有从 SmtpClient 接收到数据

问题描述

我正在尝试解决导致我通常使用的 SMTP 服务器为我自己的电子邮件地址返回“未知收件人”消息的奇怪问题。在生产中,我使用不同的 SMTP 服务器,所以这只会阻止我的测试。

我尝试使用 Fiddler 分析流量,但显然 Fiddler 没有检测到任何 SMTP 流量。我没有接受过 WireShark 的培训,这只是一个小型项目,我不能花大量时间在上面,所以我想我只是拼凑一个小型 TCP 服务,而不是看看我使用的 SmtpClient 实例发送了什么.

这是 TcpListener 代码...

class Service
{
    public Task Listen(int port, CancellationToken ct, TcpHandler tcpHandler = null)
    {
        tcpHandler = tcpHandler ?? defaultTcpHandler;
        return Task.Run(async () => 
        {
            var endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
            var listener = new TcpListener(endpoint);
            listener.Start();
            try
            {
                while (!ct.IsCancellationRequested)
                {
                    var client = await listener.AcceptTcpClientAsync();
                    handleRequestAsync(client, tcpHandler, ct);
                }
                listener.Stop();
            }
            catch (SocketException ex)
            {
                Console.WriteLine($"SocketException: {ex}");
            }
            finally
            {
                listener.Stop();
            }
        }, 
        ct);
    }

    void handleRequestAsync(TcpClient client, TcpHandler tcpHandler, CancellationToken ct)
    {
        Task.Run(async () => 
        {
            var stream = client.GetStream();
            if (!stream.CanRead)
                return;

            var sb = new StringBuilder();
            var buffer = new byte[4096];
            int receivedCount;
            while ((receivedCount = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
            {
                var received = Encoding.ASCII.GetString(buffer, 0, receivedCount);
                sb.Append(received);
            }
            var request = sb.ToString();
            if (request.Length != 0 && tcpHandler(sb.ToString(), out var response))
            {
                var send = Encoding.ASCII.GetBytes(response);
                stream.Write(send, 0, send.Length);
                stream.Flush();
            }
            client.Close();
        });
    }

是的,代码非常幼稚,没有真正的错误处理等。但是,这只是一种查看正在发送的内容的方法。问题是调用stream.ReadAsync阻塞并且永远不会返回。我还检查了 TcpClient.Available 属性,它返回零 (0)。最终 SmtpClient 超时,似乎没有发送任何内容。我也没有深入研究 SMTP 协议,所以也许我遗漏了什么?在 SmtpClient 发送数据之前,我是否需要以某种方式确认连接?

多年来我一直没有做太多的网络编码,而且我从来都不是这个领域的忍者。任何指针或提示将不胜感激。

干杯!

标签: c#networkingtcpsmtpsmtpclient

解决方案


推荐阅读