2016-08-03 1 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 

Мой сервер проходит после того, как выше Sub запускается:

  1. EHLO ("250 OK")
  2. MAIL ("250 OK")
  3. RCPT ("250 OK" на пользователя найден)
  4. DATA ("354 Первая почта ввода;. заканчиваться".)
  5. MIME ("250 OK")
  6. ТЕЛА («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

Поскольку закрытие соединения, казалось, было проблемой, добавление блока Using вокруг вашего клиента SMTP может оказаться полезным. 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 на сервер и корректно закрывает соединение.

 Смежные вопросы

  • Нет связанных вопросов^_^