1

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

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

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

  • 250 尺寸 41943040
  • 250-流水线
  • 250-DSN
  • 250 增强状态代码
  • 250-STARTTLS
  • 250-AUTH 登录
  • 250-8BITMIME
  • 250-BINARYMIME
  • 第250章

    这是课程

    导入 System.Text 导入 System.Net 导入 System.Net.Sockets 导入 System.Threading

    公共类 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

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

谢谢大家!!

坦率

4

1 回答 1

0

You will need to perform simultaneous asynchronous reading/writing between client and server to make this work properly. SMTP responses can contain any number of lines and client or server can return a message without the need for a command (to say bye for example). Parsing the data is also unnecessary to achieve a basic log.

Edit: If it helps, if the 3 digit message number if followed by a (minus) rather than a (space) it means that there is another line to follow.

于 2013-10-01T13:25:29.360 回答