SMTP 中继器日志器



我正在尝试做一个中继器(作为代理(来记录SMTP客户端和服务器之间的数据交换。我以为这很简单:倾听客户的意见;

  • 监听客户端 IP 连接;
  • 随叫随到,连接到服务器;
  • 发回服务器消息;
  • 将客户端消息发送到服务器,并将服务器反馈返回给客户端;

但是,正如我所看到的,一些服务器作为 MS 交换发送多个反馈女巫正在打破握手。喜欢:

  • 250 尺寸41943040
  • 250-流水线
  • 250-DSN
  • 250-增强状态代码
  • 250-惊动
  • 250 身份验证登录
  • 250-8位哑剧
  • 250-双哑剧
  • 250 分块

    这是类

    导入系统文本进口 System.Net导入系统.Net.Sockets导入系统线程

    公共类 SmtpProxy

    Private client As TcpClient
    Private cltstream As NetworkStream
    Private cltreader As System.IO.StreamReader
    Private cltwriter As System.IO.StreamWriter
    Private smtpserver As New TcpClient
    Private srvstream As NetworkStream
    Private srvreader As System.IO.StreamReader
    Private srvwriter As System.IO.StreamWriter
    
    Private Shared mHostSrv As String
    Public Shared Property HostSrv() As String
        Get
            Return mHostSrv
        End Get
        Set(ByVal value As String)
            mHostSrv = value
        End Set
    End Property
    Private Shared mServerPort As Integer = 25
    Public Shared Property ServerPort() As Integer
        Get
            Return mServerPort
        End Get
        Set(ByVal value As Integer
        )
            mServerPort = value
        End Set
    End Property
    Private Shared mUserNm As String
    Public Shared Property UserNm() As String
        Get
            Return mUserNm
        End Get
        Set(ByVal value As String)
            mUserNm = value
        End Set
    End Property
    Private Shared mPassword As String
    Public Shared Property Password() As String
        Get
            Return mPassword
        End Get
        Set(ByVal value As String)
            mPassword = value
        End Set
    End Property
    
    Public Sub New(ByVal client As TcpClient)
        Me.client = client
        cltstream = client.GetStream()
        cltreader = New System.IO.StreamReader(cltstream)
        cltwriter = New System.IO.StreamWriter(cltstream)
        cltwriter.NewLine = vbCr & vbLf
        cltwriter.AutoFlush = True
    End Sub
    
    Public Shared Sub Start() 'ByVal args As String())
        Dim listener As New TcpListener(IPAddress.Loopback, 2525)
        listener.Start()
        While True
            Dim handler As New SmtpProxy(listener.AcceptTcpClient())
            Dim thread As Thread = New System.Threading.Thread(New ThreadStart(AddressOf handler.Run))
            thread.Start()
        End While
    End Sub
    
    Public Sub Run()
        If mHostSrv Like "*.*.*.*" Then
            Dim IpS As IPAddress = Nothing
            IpS = IPAddress.Parse(mHostSrv)
            smtpserver.Connect(IpS, mServerPort)
        Else
            smtpserver.Connect(mHostSrv, mServerPort)
        End If
        srvstream = smtpserver.GetStream
        srvreader = New System.IO.StreamReader(srvstream)
        srvwriter = New System.IO.StreamWriter(srvstream)
        srvwriter.NewLine = vbCrLf
        srvwriter.AutoFlush = True
    
        Dim srvline As String = srvreader.ReadLine
        cltwriter.WriteLine(srvline)
        Debug.Print("Server sent: {0}", srvline & vbCrLf)
        Try
            Dim line As String = cltreader.ReadLine
            While line IsNot Nothing
                Debug.Print("Read line {0}", line)
                srvwriter.WriteLine(line)
                Application.DoEvents()
                srvline = srvreader.ReadLine()
                Debug.Print("Server sent: {0}", srvline)
                cltwriter.WriteLine(srvline.Replace("-", " "))
                Application.DoEvents()
                line = cltreader.ReadLine()
            End While
        Catch ex As Exception
            client.Close()
            smtpserver.Close()
        End Try
    End Sub
    

    结束类

我尝试一次读取多个服务器行,但与此同时,如果我发送整个返回的服务器行,客户端会返回并出错......

Private Function ReadSrvLines() As String
    Dim strRet As String = ""
    Do
        If strRet Like "220*" OrElse srvreader.EndOfStream Then Exit Do
        Dim strTmp As String = srvreader.ReadLine
        If strTmp Is Nothing Then Exit Do
        strRet &= strTmp.Replace("-", " ") & vbCrLf
        cltwriter.WriteLine(strTmp.Replace("-", " "))
        Debug.Print("Server sent: {0}", strTmp.Replace("-", " ") & vbCrLf)
    Loop
    Return strRet
End Function

那么有人有任何解决方案可以提出吗?

谢谢大家!!

弗兰克

您需要在客户端和服务器之间同时执行异步读取/写入才能正常工作。SMTP 响应可以包含任意数量的行,客户端或服务器无需命令即可返回消息(例如说再见(。解析数据也是不必要的,以实现基本日志。

编辑:如果有帮助,如果 3 位消息编号后跟(减号(而不是(空格(,则意味着还有另一行要跟。

最新更新