2016-08-03 31 views
0

我想設置一個簡單的SMTP服務器,並使用Net.Mail.SmtpClient發送消息。除了下次發送消息時,一切運行良好。只要服務器接受TCP客戶端,然後SMTP客戶端就會引發錯誤。它表示服務器提交協議違規,響應正常。異常不會阻止消息通過。這只是不乾淨,我想明白爲什麼會發生。如何正確接受SMTP郵件

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Dim smtpMail As New Net.Mail.SmtpClient 
    Dim msg As New Net.Mail.MailMessage 
    With smtpMail 
     .UseDefaultCredentials = False 
     .Port = 25 
     .EnableSsl = False 
     .Host = "127.0.0.1" 
    End With 
    With msg 
     .From = New MailAddress("[email protected]") 
     .To.Add("[email protected]") 
     .Subject = "Subject" 
     .Body = "Body" 
    End With 
    smtpMail.Send(msg) 
End Sub 

我的服務器經過上述子運行後:

  1. EHLO( 「250 OK」)
  2. MAIL( 「250 OK」)
  3. RCPT( 「250 OK」當用戶找到)
  4. DATA( 「354開始郵件輸入;結束與」。)
  5. MIME( 「250 OK」)
  6. BODY( 「250 OK」)

BODY命令後,我沒有得到進一步的答覆。

 While True 

     Dim handler As TcpClient = _Listener.AcceptTcpClient() 


     Dim smtpReady() As Byte = Encoding.ASCII.GetBytes("220 Test SMTP Service ready" & vbCrLf) 
     handler.GetStream().Write(smtpReady, 0, smtpReady.Length) 
     Dim Message As String = String.Empty 
     Try 
      While True 
       bytes = New Byte(1024) {} 
       Dim bytesRec As Integer = handler.GetStream().Read(bytes, 0, bytes.Length) 
       dta = Encoding.ASCII.GetString(bytes, 0, bytesRec) 

       Dim CMD As String = dta.Substring(0, 4).ToUpper 
       Dim ReturnCMD() As Byte = Nothing 
       Select Case CMD 
        Case HELLO 
         ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
        Case MAIL 
         ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
        Case RECIPIENT 
         Dim SentTo As String = dta.Substring(8).Trim 
         If SentTo.ToLower <> "<[email protected]>" Then 
          ReturnCMD = Encoding.ASCII.GetBytes("550 No such user here" & vbCrLf) 
          handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
         Else 
          ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
          handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
         End If 
        Case data 
         ReturnCMD = Encoding.ASCII.GetBytes("354 Start mail input; end with ." & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
        Case QUIT 
         ReturnCMD = Encoding.ASCII.GetBytes("221 Service closing transmission channel" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
         Exit While 
        Case RESET 
         ReturnCMD = Encoding.ASCII.GetBytes("221 Service closing transmission channel" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
         Exit While 
        Case EHELLO 
         ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
        Case MIME 
         ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
        Case BODY 
         Message += dta 
         RaiseEvent DataReceived(Message) 
         ReturnCMD = Encoding.ASCII.GetBytes("250 OK" & vbCrLf) 
         handler.GetStream().Write(ReturnCMD, 0, ReturnCMD.Length) 
       End Select 

      End While 

      handler.Close() 
     Catch ex As Exception 
     End Try 
    End While 

該代碼可能有一些冗餘/是混亂的。到目前爲止,這只是對別的東西的測試。我只是想搞清楚SMTP。

回答

1

由於關閉連接似乎是個問題,因此在SMTP客戶端周圍添加一個Using塊可能會很有用。 Using的行爲就像一個嘗試捕獲並安全關閉和處理任何資源連接,當它結束時End Using -

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    Using smtpMail As New Net.Mail.SmtpClient 
     Using msg As New Net.Mail.MailMessage 
      With smtpMail 
       .UseDefaultCredentials = False 
       .Port = 25 
       .EnableSsl = False 
       .Host = "127.0.0.1" 
      End With 
      With msg 
       .From = New MailAddress("[email protected]") 
       .To.Add("[email protected]") 
       .Subject = "Subject" 
       .Body = "Body" 
      End With 
      smtpMail.Send(msg) 
     End Using 
    End Using 
End Sub 
0

調用SmtpClient.Dispose解決了我的問題。這會向服務器發送QUIT,並正常關閉連接。