powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / А про IMAP не разжуете?
15 сообщений из 40, страница 2 из 2
А про IMAP не разжуете?
    #38964110
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesимхо использовать протоколы IMAP, POP, SMTP это вообще плохая идея,эти протоколы древние как говно мамонта.ага, попроси мир больше никогда не пользоваться электронной почтой.

Roman Mejtesбезопасность этих протокол отдыхаетих безопасность обеспечивает тот же механизм, что обеспечивает безопасность https, нужно только его задействовать, поставив где надо галочки. или на https у тебя тоже зуб есть?

Roman MejtesА писать свой pop3, imap клиент, это написание велосипеда, все же давно уже по 100500 раз написано никто и не пишет с нуля, обычно из готового велосипеда выдирают раму, а колеса прикручивают куда требуется.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964185
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyRoman Mejtesимхо использовать протоколы IMAP, POP, SMTP это вообще плохая идея,эти протоколы древние как говно мамонта.ага, попроси мир больше никогда не пользоваться электронной почтой.
я сам удивляюсь тому, что в эпоху мгновенной передачи цифровых сообщений этим говном до сих пор все пользуются =)
могли бы уже что то новое придумать :)
Roman MejtesА писать свой pop3, imap клиент, это написание велосипеда, все же давно уже по 100500 раз написано никто и не пишет с нуля, обычно из готового велосипеда выдирают раму, а колеса прикручивают куда требуется.
дык автор то, судя по теме свой пилит, через сокеты цепляется и фигачит.. Дело хозяйское конечно, если надо , пусть страдает :)
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964207
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtesдык автор то, судя по теме свой пилит, через сокеты цепляется и фигачит.. Дело хозяйское конечно, если надо , пусть страдает :)ну, автор и колеса разобрал :)
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964365
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я могу сказать, на чем я принципиально споткнулся пытаясь переделать POP3 в IMAP:
Дмитрий77Antonariy,
я так понимаю из твоего кода и твоих комментариев, что принцип общения с POP3 и IMAP абсолютно одинаков:
команда ->
<- ответ
анализ ответа
При необходимости оборачиваем в SSL-stream (вот здесь чувствуются преимущества .Net).
Так?

Т.е. получается что если класс для POP3 я передрал/написал (ага, 1009 строк):

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
Imports System.Net.Sockets
Imports System.Net.Security
Imports System.IO
Imports System.Text

Module ModulePop3

  Public Sub GetMail(ByVal m_PopServer As String, ByVal m_User As String, ByVal m_Password As String, _
   Optional ByVal m_ServerPort As Integer = 110, Optional ByVal m_useSSL As Boolean = False, _
   Optional ByVal m_DeleteEmails As Boolean = True, Optional ByVal m_SaveDir As String = vbNullString, _
   Optional ByVal m_SaveMailPrefix As String = "MSG", Optional ByVal m_SaveMailExt As String = ".eml", _
   Optional ByVal m_TraceFunction As Pop3.TraceHandler = Nothing, Optional ByVal m_TestMode As Boolean = False)

    If m_TraceFunction IsNot Nothing AndAlso m_TestMode = False Then m_TraceFunction("-------------------------")
    Try
      ' prepare pop client
      Dim POP3Client As Pop3.cPop3MailClient = _
       New Pop3.cPop3MailClient(m_PopServer, m_ServerPort, m_useSSL, m_User, m_Password)
      POP3Client.IsAutoReconnect = True

      'if tracing needed
      If m_TraceFunction IsNot Nothing Then AddHandler POP3Client.Trace, m_TraceFunction

      POP3Client.ReadTimeout = 60000 'give pop server 60 seconds to answer

      'establish connection
      POP3Client.Connect()

      'get mailbox statistics
      Dim NumberOfMails As Integer, MailboxSize As Integer
      POP3Client.GetMailboxStats(NumberOfMails, MailboxSize)

      If m_TestMode Then
        'get a list of mails
        Dim EmailIds As New List(Of Integer)
        POP3Client.GetEmailIdList(EmailIds)

        'get a list of unique mail ids
        Dim EmailUids As New List(Of Pop3.EmailUid)
        POP3Client.GetUniqueEmailIdList(EmailUids)

        'only show info
        If NumberOfMails > 0 Then
          For i As Integer = 1 To NumberOfMails
            'get email size
            POP3Client.GetEmailSize(i)
          Next
        End If

        'ping server
        POP3Client.NOOP()

      Else

        'get emails
        If NumberOfMails > 0 Then

          If Strings.Len(m_SaveDir) = 0 OrElse IO.Directory.Exists(m_SaveDir) = False Then _
           m_SaveDir = Application.StartupPath
          If Strings.Len(m_SaveMailPrefix) = 0 Then m_SaveMailPrefix = "MSG"
          If Strings.Len(m_SaveMailExt) = 0 Then m_SaveMailExt = ".eml"
          If Strings.Left(m_SaveMailExt, 1) <> "." Then m_SaveMailExt = "." & m_SaveMailExt

          For i As Integer = 1 To NumberOfMails
            'get email size
            POP3Client.GetEmailSize(i)

            'get email
            Dim Email As String = ""
            POP3Client.GetRawEmail(i, Email)
            If Strings.Len(Email) > 0 Then
              Dim fToSave As String = GetNextEmailFileName(m_SaveDir, m_SaveMailPrefix, m_SaveMailExt)
              Try : IO.File.WriteAllText(fToSave, Email, System.Text.Encoding.ASCII) : Catch : End Try
            End If

            'delete email
            If m_DeleteEmails Then POP3Client.DeleteEmail(i)
          Next
        End If
      End If

      'close connection
      POP3Client.Disconnect()

    Catch ex As Exception
      If m_TraceFunction IsNot Nothing Then
        m_TraceFunction("Run Time Error Occured:")
        m_TraceFunction(ex.Message)
        m_TraceFunction(ex.StackTrace)
      End If
    End Try
    If m_TraceFunction IsNot Nothing AndAlso m_TestMode = False Then m_TraceFunction("-------------------------")

  End Sub

  Private Function GetNextEmailFileName(ByVal path As String, ByVal pref As String, ByVal ext As String) As String
    Dim tmp_name As String
    Dim i As Integer = 0
    Do
      i = i + 1
      tmp_name = IO.Path.Combine(path, pref & i.ToString & ext)
      If IO.File.Exists(tmp_name) = False Then Return tmp_name
    Loop
  End Function

End Module

Namespace Pop3
  ' Supporting classes and structs
  ' ==============================

  ''' <summary>
  ''' Combines Email ID with Email UID for one email
  ''' The POP3 server assigns to each message a unique Email UID, which will not change for the life time
  ''' of the message and no other message should use the same.
  ''' 
  ''' Exceptions:
  ''' Throws Pop3Exception if there is a serious communication problem with the POP3 server, otherwise
  ''' 
  ''' </summary>
  Public Structure EmailUid
    ''' <summary>
    ''' used in POP3 commands to indicate which message (only valid in the present session)
    ''' </summary>
    Public EmailId As Integer
    ''' <summary>
    ''' Uid is always the same for a message, regardless of session
    ''' </summary>
    Public Uid As String

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="EmailId"></param>
    ''' <param name="Uid"></param>
    Public Sub New(EmailId As Integer, Uid As String)
      Me.EmailId = EmailId
      Me.Uid = Uid
    End Sub
  End Structure

  ''' <summary>
  ''' If anything goes wrong within Pop3MailClient, a Pop3Exception is raised
  ''' </summary>
  Public Class Pop3Exception
    Inherits ApplicationException
    ''' <summary>
    ''' 
    ''' </summary>
    Public Sub New()
    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="ErrorMessage"></param>
    Public Sub New(ByVal ErrorMessage As String)
      MyBase.New(ErrorMessage)
    End Sub
  End Class

  ''' <summary>
  ''' A pop 3 connection goes through the following states:
  ''' </summary>
  Public Enum Pop3ConnectionStateEnum
    ''' <summary>
    ''' undefined
    ''' </summary>
    None = 0
    ''' <summary>
    ''' not connected yet to POP3 server
    ''' </summary>
    Disconnected
    ''' <summary>
    ''' TCP connection has been opened and the POP3 server has sent the greeting. POP3 server expects user name and password
    ''' </summary>
    Authorization
    ''' <summary>
    ''' client has identified itself successfully with the POP3, server has locked all messages 
    ''' </summary>
    Connected
    ''' <summary>
    ''' QUIT command was sent, the server has deleted messages marked for deletion and released the resources
    ''' </summary>
    Closed
  End Enum

  ' Delegates for Pop3MailClient
  ' ============================

  ''' <summary>
  ''' If POP3 Server doesn't react as expected or this code has a problem, but
  ''' can continue with the execution, a Warning is called.
  ''' </summary>
  ''' <param name="WarningText"></param>
  ''' <param name="Response">string received from POP3 server</param>
  Public Delegate Sub WarningHandler(ByVal WarningText As String, ByVal Response As String)

  ''' <summary>
  ''' Traces all the information exchanged between POP3 client and POP3 server plus some
  ''' status messages from POP3 client.
  ''' Helpful to investigate any problem.
  ''' Console.WriteLine() can be used
  ''' </summary>
  ''' <param name="TraceText"></param>
  Public Delegate Sub TraceHandler(ByVal TraceText As String)

  ' cPop3MailClient Class
  ' ====================  

  ''' <summary>
  ''' provides access to emails on a POP3 Server
  ''' </summary>
  Public Class cPop3MailClient

    'Events
    '------

    ''' <summary>
    ''' Called whenever POP3 server doesn't react as expected, but no runtime error is thrown.
    ''' </summary>
    Public Event Warning As WarningHandler

    ''' <summary>
    ''' call warning event
    ''' </summary>
    ''' <param name="methodName">name of the method where warning is needed</param>
    ''' <param name="response">answer from POP3 server causing the warning</param>
    ''' <param name="warningText">explanation what went wrong</param>
    ''' <param name="warningParameters"></param>
    Protected Sub CallWarning(ByVal methodName As String, ByVal response As String, _
     ByVal warningText As String, ByVal ParamArray warningParameters As Object())
      warningText = String.Format(warningText, warningParameters)
      RaiseEvent Warning(Convert.ToString(methodName & Convert.ToString(": ")) & warningText, response)
      CallTrace("!! {0}", warningText)
    End Sub

    ''' <summary>
    ''' Shows the communication between PopClient and PopServer, including warnings
    ''' </summary>
    Public Event Trace As TraceHandler

    ''' <summary>
    ''' call Trace event
    ''' </summary>
    ''' <param name="text">string to be traced</param>
    ''' <param name="parameters"></param>
    Protected Sub CallTrace(ByVal text As String, ByVal ParamArray parameters As Object())
      'RaiseEvent Trace(DateTime.Now.ToString("hh:mm:ss ") + m_popServer + " " + String.Format(text, parameters))
      RaiseEvent Trace(DateTime.Now.ToString + Chr(9) + m_popServer + Chr(9) + String.Format(text, parameters))
    End Sub

    ''' <summary>
    ''' Trace information received from POP3 server
    ''' </summary>
    ''' <param name="text">string to be traced</param>
    ''' <param name="parameters"></param>
    Protected Sub TraceFrom(ByVal text As String, ByVal ParamArray parameters As Object())
      CallTrace("   " + String.Format(text, parameters))
    End Sub

    'Properties
    '------

    ''' <summary>
    ''' Get POP3 server name
    ''' </summary>
    Public ReadOnly Property PopServer() As String
      Get
        Return m_popServer
      End Get
    End Property
    ''' <summary>
    ''' POP3 server name
    ''' </summary>
    Protected m_popServer As String

    ''' <summary>
    ''' Get POP3 server port
    ''' </summary>
    Public ReadOnly Property Port() As Integer
      Get
        Return m_port
      End Get
    End Property
    ''' <summary>
    ''' POP3 server port
    ''' </summary>
    Protected m_port As Integer

    ''' <summary>
    ''' Should SSL be used for connection with POP3 server ?
    ''' </summary>
    Public ReadOnly Property UseSSL() As Boolean
      Get
        Return m_useSSL
      End Get
    End Property
    ''' <summary>
    ''' Should SSL be used for connection with POP3 server ?
    ''' </summary>
    Private m_useSSL As Boolean

    ''' <summary>
    ''' should Pop3MailClient automatically reconnect if POP3 server has dropped the 
    ''' connection due to a timeout ?
    ''' </summary>
    Public Property IsAutoReconnect() As Boolean
      Get
        Return m_isAutoReconnect
      End Get
      Set(ByVal value As Boolean)
        m_isAutoReconnect = value
      End Set
    End Property
    Private m_isAutoReconnect As Boolean = False
    'timeout has occured, we try to perform an autoreconnect
    Private isTimeoutReconnect As Boolean = False

    ''' <summary>
    ''' Get / set read timeout (miliseconds)
    ''' </summary>
    Public Property ReadTimeout() As Integer
      Get
        Return m_readTimeout
      End Get
      Set(ByVal value As Integer)
        m_readTimeout = value
        If pop3Stream IsNot Nothing AndAlso pop3Stream.CanTimeout Then
          pop3Stream.ReadTimeout = m_readTimeout
        End If
      End Set
    End Property
    ''' <summary>
    ''' POP3 server read timeout
    ''' </summary>
    Protected m_readTimeout As Integer = -1

    ''' <summary>
    ''' Get owner name of mailbox on POP3 server
    ''' </summary>
    Public ReadOnly Property Username() As String
      Get
        Return m_username
      End Get
    End Property
    ''' <summary>
    ''' Owner name of mailbox on POP3 server
    ''' </summary>
    Protected m_username As String

    ''' <summary>
    ''' Get password for mailbox on POP3 server
    ''' </summary>
    Public ReadOnly Property Password() As String
      Get
        Return m_password
      End Get
    End Property
    ''' <summary>
    ''' Password for mailbox on POP3 server
    ''' </summary>
    Protected m_password As String

    ''' <summary>
    ''' Get connection status with POP3 server
    ''' </summary>
    Public ReadOnly Property Pop3ConnectionState() As Pop3ConnectionStateEnum
      Get
        Return m_pop3ConnectionState
      End Get
    End Property
    ''' <summary>
    ''' connection status with POP3 server
    ''' </summary>
    Protected m_pop3ConnectionState As Pop3ConnectionStateEnum = Pop3ConnectionStateEnum.Disconnected

    ' Methods
    ' -------

    ''' <summary>
    ''' set POP3 connection state
    ''' </summary>
    ''' <param name="State"></param>
    Protected Sub setPop3ConnectionState(ByVal State As Pop3ConnectionStateEnum)
      m_pop3ConnectionState = State
      CallTrace("   Pop3MailClient Connection State {0} reached", State)
    End Sub

    ''' <summary>
    ''' throw exception if POP3 connection is not in the required state
    ''' </summary>
    ''' <param name="requiredState"></param>
    Protected Sub EnsureState(ByVal requiredState As Pop3ConnectionStateEnum)
      If m_pop3ConnectionState <> requiredState Then
        ' wrong connection state
        Throw New Pop3Exception("GetMailboxStats only accepted during connection state: " + requiredState.ToString() + _
         vbLf & " The connection to server " + m_popServer + " is in state " + m_pop3ConnectionState.ToString())
      End If
    End Sub

    'private fields
    '--------------
    ''' <summary>
    ''' TCP to POP3 server
    ''' </summary>
    Private serverTcpConnection As TcpClient
    ''' <summary>
    ''' Stream from POP3 server with or without SSL
    ''' </summary>
    Private pop3Stream As Stream
    ''' <summary>
    ''' Reader for POP3 message
    ''' </summary>
    Protected pop3StreamReader As StreamReader
    ''' <summary>
    ''' char 'array' for carriage return / line feed
    ''' </summary>
    Protected CRLF As String = vbCr & vbLf

    'public methods
    '--------------

    ''' <summary>
    ''' Make POP3 client ready to connect to POP3 server
    ''' </summary>
    ''' <param name="PopServer"><example>pop.gmail.com</example></param>
    ''' <param name="Port"><example>995</example></param>
    ''' <param name="useSSL">True: SSL is used for connection to POP3 server</param>
    ''' <param name="Username"><example>abc@gmail.com<;/example></param>
    ''' <param name="Password">Secret</param>
    Public Sub New(ByVal PopServer As String, ByVal Port As Integer, ByVal useSSL As Boolean, _
     ByVal Username As String, ByVal Password As String)
      Me.m_popServer = PopServer
      Me.m_port = Port
      Me.m_useSSL = useSSL
      Me.m_username = Username
      Me.m_password = Password
    End Sub

    ''' <summary>
    ''' Connect to POP3 server
    ''' </summary>
    Public Sub Connect()
      If (m_pop3ConnectionState <> Pop3ConnectionStateEnum.Disconnected) AndAlso
       (m_pop3ConnectionState <> Pop3ConnectionStateEnum.Closed) AndAlso
       (Not isTimeoutReconnect) Then
        CallWarning("connect", "", "Connect command received, but connection state is: " + m_pop3ConnectionState.ToString())
      Else
        'establish TCP connection
        Try
          CallTrace("   Connect at port {0}", m_port)
          serverTcpConnection = New TcpClient(m_popServer, m_port)
        Catch ex As Exception
          Throw New Pop3Exception("Connection to server " + m_popServer + ", port " + m_port.ToString + " failed." & vbLf & "Runtime Error: " + ex.ToString())
        End Try

        If m_useSSL Then
          'get SSL stream
          Try
            CallTrace("   Get SSL connection")
            pop3Stream = New SslStream(serverTcpConnection.GetStream(), False)
            pop3Stream.ReadTimeout = m_readTimeout
          Catch ex As Exception
            Throw New Pop3Exception("Server " + m_popServer + " found, but cannot get SSL data stream." & vbLf & "Runtime Error: " + ex.ToString())
          End Try

          'perform SSL authentication
          Try
            CallTrace("   Get SSL authentication")
            DirectCast(pop3Stream, SslStream).AuthenticateAsClient(m_popServer)
          Catch ex As Exception
            Throw New Pop3Exception("Server " + m_popServer + " found, but problem with SSL Authentication." & vbLf & "Runtime Error: " + ex.ToString())
          End Try
        Else
          'create a stream to POP3 server without using SSL
          Try
            CallTrace("   Get connection without SSL")
            pop3Stream = serverTcpConnection.GetStream()
            pop3Stream.ReadTimeout = m_readTimeout
          Catch ex As Exception
            Throw New Pop3Exception("Server " + m_popServer + " found, but cannot get data stream (without SSL)." & vbLf & "Runtime Error: " + ex.ToString())
          End Try
        End If

        'get stream for reading from pop server
        'POP3 allows only US-ASCII. The message will be translated in the proper encoding in a later step
        Try
          pop3StreamReader = New StreamReader(pop3Stream, Encoding.ASCII)
        Catch ex As Exception
          If m_useSSL Then
            Throw New Pop3Exception("Server " + m_popServer + " found, but cannot read from SSL stream." & vbLf & "Runtime Error: " + ex.ToString())
          Else
            Throw New Pop3Exception("Server " + m_popServer + " found, but cannot read from stream (without SSL)." & vbLf & "Runtime Error: " + ex.ToString())
          End If
        End Try

        'ready for authorisation
        Dim response As String = ""
        If Not readSingleLine(response) Then
          Throw New Pop3Exception(Convert.ToString("Server " + m_popServer + " not ready to start AUTHORIZATION." & vbLf & "Message: ") & response)
        End If
        setPop3ConnectionState(Pop3ConnectionStateEnum.Authorization)

        'send user name
        If Not executeCommand("USER " + m_username, response) Then
          Throw New Pop3Exception(Convert.ToString("Server " + m_popServer + " doesn't accept username '" + m_username + "'." & vbLf & "Message: ") & response)
        End If

        'send password
        If Not executeCommand("PASS " + m_password, response) Then
          Throw New Pop3Exception(Convert.ToString("Server " + m_popServer + " doesn't accept password '" + m_password + "' for user '" + m_username + "'." & vbLf & "Message: ") & response)
        End If

        setPop3ConnectionState(Pop3ConnectionStateEnum.Connected)
      End If
    End Sub

    ''' <summary>
    ''' Disconnect from POP3 Server
    ''' </summary>
    Public Sub Disconnect()
      If m_pop3ConnectionState = Pop3ConnectionStateEnum.Disconnected OrElse _
       m_pop3ConnectionState = Pop3ConnectionStateEnum.Closed Then
        CallWarning("disconnect", "", "Disconnect received, but was already disconnected.")
      Else
        'ask server to end session and possibly to remove emails marked for deletion
        Try
          Dim response As String = ""
          If executeCommand("QUIT", response) Then
            'server says everything is ok
            setPop3ConnectionState(Pop3ConnectionStateEnum.Closed)
          Else
            'server says there is a problem
            CallWarning("Disconnect", response, Convert.ToString("negative response from server while closing connection: ") & response)
            setPop3ConnectionState(Pop3ConnectionStateEnum.Disconnected)
          End If
        Finally
          'close connection
          If pop3Stream IsNot Nothing Then
            pop3Stream.Close()
          End If

          pop3StreamReader.Close()
        End Try
      End If
    End Sub

    ''' <summary>
    ''' Delete message from server.
    ''' The POP3 server marks the message as deleted.  Any future
    ''' reference to the message-number associated with the message
    ''' in a POP3 command generates an error.  The POP3 server does
    ''' not actually delete the message until the POP3 session
    ''' enters the UPDATE state.
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <returns></returns>
    Public Function DeleteEmail(ByVal msg_number As Integer) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      Dim response As String = ""
      If Not executeCommand("DELE " + msg_number.ToString(), response) Then
        CallWarning("DeleteEmail", response, "negative response for email (Id: {0}) delete request", msg_number)
        Return False
      End If
      Return True
    End Function

    ''' <summary>
    ''' Get a list of all Email IDs available in mailbox
    ''' </summary>
    ''' <returns></returns>
    Public Function GetEmailIdList(ByRef EmailIds As List(Of Integer)) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      EmailIds = New List(Of Integer)()

      'get server response status line
      Dim response As String = ""
      If Not executeCommand("LIST", response) Then
        CallWarning("GetEmailIdList", response, "negative response for email list request")
        Return False
      End If

      'get every email id
      Dim EmailId As Integer
      While readMultiLine(response)
        If Integer.TryParse(response.Split(" "c)(0), EmailId) Then
          EmailIds.Add(EmailId)
        Else
          CallWarning("GetEmailIdList", response, "first characters should be integer (EmailId)")
        End If
      End While
      TraceFrom("{0} email ids received", EmailIds.Count)
      Return True
    End Function

    ''' <summary>
    ''' get size of one particular email
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <returns></returns>
    Public Function GetEmailSize(ByVal msg_number As Integer) As Integer
      EnsureState(Pop3ConnectionStateEnum.Connected)
      Dim response As String = ""
      executeCommand("LIST " + msg_number.ToString(), response)
      Dim EmailSize As Integer = 0
      Dim responseSplit As String() = response.Split(" "c)
      If responseSplit.Length < 2 OrElse Not Integer.TryParse(responseSplit(2), EmailSize) Then
        CallWarning("GetEmailSize", response, "'+OK int int' format expected (EmailId, EmailSize)")
      End If

      Return EmailSize
    End Function

    ''' <summary>
    ''' Get a list with the unique IDs of all Email available in mailbox.
    ''' 
    ''' Explanation:
    ''' EmailIds for the same email can change between sessions, whereas the unique Email id
    ''' never changes for an email.
    ''' </summary>
    ''' <param name="EmailIds"></param>
    ''' <returns></returns>
    Public Function GetUniqueEmailIdList(ByRef EmailIds As List(Of EmailUid)) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      EmailIds = New List(Of EmailUid)()

      'get server response status line
      Dim response As String = ""
      If Not executeCommand("UIDL ", response) Then
        CallWarning("GetUniqueEmailIdList", response, "negative response for email list request")
        Return False
      End If

      'get every email unique id
      Dim EmailId As Integer
      While readMultiLine(response)
        Dim responseSplit As String() = response.Split(" "c)
        If responseSplit.Length < 2 Then
          CallWarning("GetUniqueEmailIdList", response, "response not in format 'int string'")
        ElseIf Not Integer.TryParse(responseSplit(0), EmailId) Then
          CallWarning("GetUniqueEmailIdList", response, "first charaters should be integer (Unique EmailId)")
        Else
          EmailIds.Add(New EmailUid(EmailId, responseSplit(1)))
        End If
      End While
      TraceFrom("{0} unique email ids received", EmailIds.Count)
      Return True
    End Function

    ''' <summary>
    ''' get a list with all currently available messages and the UIDs
    ''' </summary>
    ''' <param name="EmailIds">EmailId Uid list</param>
    ''' <returns>false: server sent negative response (didn't send list)</returns>
    Public Function GetUniqueEmailIdList(ByRef EmailIds As SortedList(Of String, Integer)) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      EmailIds = New SortedList(Of String, Integer)()

      'get server response status line
      Dim response As String = ""
      If Not executeCommand("UIDL", response) Then
        CallWarning("GetUniqueEmailIdList", response, "negative response for email list request")
        Return False
      End If

      'get every email unique id
      Dim EmailId As Integer
      While readMultiLine(response)
        Dim responseSplit As String() = response.Split(" "c)
        If responseSplit.Length < 2 Then
          CallWarning("GetUniqueEmailIdList", response, "response not in format 'int string'")
        ElseIf Not Integer.TryParse(responseSplit(0), EmailId) Then
          CallWarning("GetUniqueEmailIdList", response, "first charaters should be integer (Unique EmailId)")
        Else
          EmailIds.Add(responseSplit(1), EmailId)
        End If
      End While
      TraceFrom("{0} unique email ids received", EmailIds.Count)
      Return True
    End Function

    ''' <summary>
    ''' get size of one particular email
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <returns></returns>
    Public Function GetUniqueEmailId(ByVal msg_number As EmailUid) As Integer
      EnsureState(Pop3ConnectionStateEnum.Connected)
      Dim response As String = ""
      executeCommand("LIST " + msg_number.ToString(), response)
      Dim EmailSize As Integer = 0
      Dim responseSplit As String() = response.Split(" "c)
      If responseSplit.Length < 2 OrElse Not Integer.TryParse(responseSplit(2), EmailSize) Then
        CallWarning("GetEmailSize", response, "'+OK int int' format expected (EmailId, EmailSize)")
      End If

      Return EmailSize
    End Function

    ''' <summary>
    ''' Sends an 'empty' command to the POP3 server. Server has to respond with +OK
    ''' </summary>
    ''' <returns>true: server responds as expected</returns>
    Public Function NOOP() As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      Dim response As String = ""
      If Not executeCommand("NOOP", response) Then
        CallWarning("NOOP", response, "negative response for NOOP request")
        Return False
      End If
      Return True
    End Function

    ''' <summary>
    ''' Should the raw content, the US-ASCII code as received, be traced
    ''' GetRawEmail will switch it on when it starts and off once finished
    ''' 
    ''' Inheritors might use it to get the raw email
    ''' </summary>
    Protected isTraceRawEmail As Boolean = False


    ''' <summary>
    ''' contains one MIME part of the email in US-ASCII, needs to be translated in .NET string (Unicode)
    ''' contains the complete email in US-ASCII, needs to be translated in .NET string (Unicode)
    ''' For speed reasons, reuse StringBuilder
    ''' </summary>
    Protected RawEmailSB As StringBuilder

    ''' <summary>
    ''' Reads the complete text of a message
    ''' </summary>
    ''' <param name="MessageNo">Email to retrieve</param>
    ''' <param name="EmailText">ASCII string of complete message</param>
    ''' <returns></returns>
    Public Function GetRawEmail(ByVal MessageNo As Integer, ByRef EmailText As String) As Boolean
      'send 'RETR int' command to server
      If Not SendRetrCommand(MessageNo) Then
        EmailText = Nothing
        Return False
      End If

      'get the lines
      Dim response As String = ""
      Dim LineCounter As Integer = 0
      'empty StringBuilder
      If RawEmailSB Is Nothing Then
        RawEmailSB = New StringBuilder(100000)
      Else
        RawEmailSB.Length = 0
      End If
      isTraceRawEmail = True
      While readMultiLine(response)
        LineCounter += 1
      End While
      EmailText = RawEmailSB.ToString()
      TraceFrom("email with {0} lines,  {1} chars received", LineCounter.ToString(), EmailText.Length)
      Return True
    End Function

    ' ''' <summary>
    ' ''' Requests from POP3 server a specific email and returns a stream with the message content (header and body)
    ' ''' </summary>
    ' ''' <param name="MessageNo"></param>
    ' ''' <param name="EmailStreamReader"></param>
    ' ''' <returns>false: POP3 server cannot provide this message</returns>
    'Public Function GetEmailStream(ByVal MessageNo As Integer, ByRef EmailStreamReader As StreamReader) As Boolean
    '  'send 'RETR int' command to server
    '  If Not SendRetrCommand(MessageNo) Then
    '    EmailStreamReader = Nothing
    '    Return False
    '  End If
    '  EmailStreamReader = sslStreamReader
    '  Return True
    'End Function

    ''' <summary>
    ''' Unmark any emails from deletion. The server only deletes email really
    ''' once the connection is properly closed.
    ''' </summary>
    ''' <returns>true: emails are unmarked from deletion</returns>
    Public Function UndeleteAllEmails() As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      Dim response As String = ""
      Return executeCommand("RSET", response)
    End Function

    ''' <summary>
    ''' Get mailbox statistics
    ''' </summary>
    ''' <param name="NumberOfMails"></param>
    ''' <param name="MailboxSize"></param>
    ''' <returns></returns>
    Public Function GetMailboxStats(ByRef NumberOfMails As Integer, ByRef MailboxSize As Integer) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)

      'interpret response
      Dim response As String = ""
      NumberOfMails = 0
      MailboxSize = 0
      If executeCommand("STAT", response) Then
        'got a positive response
        Dim responseParts As String() = response.Split(" "c)
        If responseParts.Length < 2 Then
          'response format wrong
          Throw New Pop3Exception(Convert.ToString("Server " + m_popServer + " sends illegally formatted response." + _
           vbLf & "Expected format: +OK int int" + _
           vbLf & "Received response: ") & response)
        End If
        NumberOfMails = Integer.Parse(responseParts(1))
        MailboxSize = Integer.Parse(responseParts(2))
        Return True
      End If
      Return False
    End Function

    ''' <summary>
    ''' Send RETR command to POP 3 server to fetch one particular message
    ''' </summary>
    ''' <param name="MessageNo">ID of message required</param>
    ''' <returns>false: negative server respond, message not delivered</returns>
    Protected Function SendRetrCommand(ByVal MessageNo As Integer) As Boolean
      EnsureState(Pop3ConnectionStateEnum.Connected)
      ' retrieve mail with message number
      Dim response As String = ""
      If Not executeCommand("RETR " + MessageNo.ToString(), response) Then
        CallWarning("GetRawEmail", response, "negative response for email (ID: {0}) request", MessageNo)
        Return False
      End If
      Return True
    End Function

    'Helper methodes
    '---------------

    Public isDebug As Boolean = False

    ''' <summary>
    ''' sends the 4 letter command to POP3 server (adds CRLF) and waits for the
    ''' response of the server
    ''' </summary>
    ''' <param name="command">command to be sent to server</param>
    ''' <param name="response">answer from server</param>
    ''' <returns>false: server sent negative acknowledge, i.e. server could not execute command</returns>
    Private Function executeCommand(ByVal command As String, ByRef response As String) As Boolean
      'send command to server
      Dim commandBytes As Byte() = System.Text.Encoding.ASCII.GetBytes((command & CRLF).ToCharArray())
      CallTrace("Tx '{0}'", command)
      Dim isSupressThrow As Boolean = False
      Try
        pop3Stream.Write(commandBytes, 0, commandBytes.Length)
        If isDebug Then
          isDebug = False
          Throw New IOException("Test", New SocketException(10053))
        End If
      Catch ex As IOException
        'Unable to write data to the transport connection. Check if reconnection should be tried
        isSupressThrow = executeReconnect(ex, command, commandBytes)
        If Not isSupressThrow Then
          Throw
        End If
      End Try
      pop3Stream.Flush()

      'read response from server
      response = Nothing
      Try
        response = pop3StreamReader.ReadLine()
      Catch ex As IOException
        'Unable to write data to the transport connection. Check if reconnection should be tried
        isSupressThrow = executeReconnect(ex, command, commandBytes)
        If isSupressThrow Then
          'wait for response one more time
          response = pop3StreamReader.ReadLine()
        Else
          Throw
        End If
      End Try
      If response Is Nothing Then
        Throw New Pop3Exception("Server " + m_popServer + " has not responded, timeout has occured.")
      End If
      CallTrace("Rx '{0}'", response)
      Return (response.Length > 0 AndAlso response(0) = "+"c)
    End Function

    ''' <summary>
    ''' reconnect, if there is a timeout exception and isAutoReconnect is true
    ''' 
    ''' </summary>
    Private Function executeReconnect(ByVal ex As IOException, ByVal command As String, _
     ByVal commandBytes As Byte()) As Boolean
      If ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is SocketException Then
        'SocketException
        Dim innerEx As SocketException = DirectCast(ex.InnerException, SocketException)
        If innerEx.ErrorCode = 10053 Then
          'probably timeout: An established connection was aborted by the software in your host machine.
          CallWarning("ExecuteCommand", "", "probably timeout occured")
          If m_isAutoReconnect Then
            'try to reconnect and send one more time
            isTimeoutReconnect = True
            Try
              CallTrace("   try to auto reconnect")
              Connect()

              CallTrace("   reconnect successful, try to resend command")
              CallTrace("Tx '{0}'", command)
              pop3Stream.Write(commandBytes, 0, commandBytes.Length)
              pop3Stream.Flush()
              Return True
            Finally
              isTimeoutReconnect = False
            End Try

          End If
        End If
      End If
      Return False
    End Function

    ' ''' <summary>
    ' ''' sends the 4 letter command to POP3 server (adds CRLF)
    ' ''' </summary>
    ' ''' <param name="command"></param>
    'Protected Sub SendCommand(ByVal command As String)
    '  Dim commandBytes As Byte() = System.Text.Encoding.ASCII.GetBytes((command & CRLF).ToCharArray())
    '  CallTrace("Tx '{0}'", command)
    '  Try
    '    pop3Stream.Write(commandBytes, 0, commandBytes.Length)
    '  Catch ex As IOException
    '    'Unable to write data to the transport connection:
    '    If ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is SocketException Then
    '      'SocketException
    '      Dim innerEx As SocketException = DirectCast(ex.InnerException, SocketException)
    '      If innerEx.ErrorCode = 10053 Then
    '        'probably timeout: An established connection was aborted by the software in your host machine.
    '        CallWarning("SendCommand", "", "probably timeout occured")
    '        If m_isAutoReconnect Then
    '          'try to reconnect and send one more time
    '          isTimeoutReconnect = True
    '          Try
    '            CallTrace("   try to auto reconnect")
    '            Connect()

    '            CallTrace("   reconnect successful, try to resend command")
    '            CallTrace("Tx '{0}'", command)
    '            pop3Stream.Write(commandBytes, 0, commandBytes.Length)
    '          Finally
    '            isTimeoutReconnect = False
    '          End Try
    '          Return
    '        End If
    '      End If
    '    End If
    '    Throw
    '  End Try
    '  pop3Stream.Flush()
    'End Sub

    ''' <summary>
    ''' read single line response from POP3 server. 
    ''' <example>Example server response: +OK asdfkjahsf</example>
    ''' </summary>
    ''' <param name="response">response from POP3 server</param>
    ''' <returns>true: positive response</returns>
    Protected Function readSingleLine(ByRef response As String) As Boolean
      response = Nothing
      Try
        response = pop3StreamReader.ReadLine()
      Catch ex As Exception
        Dim s As String = ex.Message
      End Try
      If response Is Nothing Then
        Throw New Pop3Exception("Server " + m_popServer + " has not responded, timeout has occured.")
      End If
      CallTrace("Rx '{0}'", response)
      Return (response.Length > 0 AndAlso response(0) = "+"c)
    End Function

    ''' <summary>
    ''' read one line in multiline mode from the POP3 server. 
    ''' </summary>
    ''' <param name="response">line received</param>
    ''' <returns>false: end of message</returns>
    Protected Function readMultiLine(ByRef response As String) As Boolean
      response = Nothing
      response = pop3StreamReader.ReadLine()
      If response Is Nothing Then
        Throw New Pop3Exception("Server " + m_popServer + " has not responded, probably timeout has occured.")
      End If
      If isTraceRawEmail Then
        'collect all responses as received
        RawEmailSB.Append(response & CRLF)
      End If
      'check for byte stuffing, i.e. if a line starts with a '.', another '.' is added, unless
      'it is the last line
      If response.Length > 0 AndAlso response(0) = "."c Then
        If response = "." Then
          'closing line found
          Return False
        End If
        'remove the first '.'
        response = response.Substring(1, response.Length - 1)
      End If
      Return True
    End Function

  End Class

End Namespace


то мне его просто надо переделать в IMAP? Насколько тяжело?

Ну, вот POP3 дебаг(скачиваем единственное письмо, с удалением на сервере)

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
19.05.2015 16:41:23	pop.gmail.com	   Connect at port 995
19.05.2015 16:41:23	pop.gmail.com	   Get SSL connection
19.05.2015 16:41:23	pop.gmail.com	   Get SSL authentication
19.05.2015 16:41:23	pop.gmail.com	Rx '+OK Gpop ready for requests from 176.17.213.145 c128mb48153737lfb'
19.05.2015 16:41:23	pop.gmail.com	   Pop3MailClient Connection State Authorization reached
19.05.2015 16:41:23	pop.gmail.com	Tx 'USER username@gmail.com'
19.05.2015 16:41:23	pop.gmail.com	Rx '+OK send PASS'
19.05.2015 16:41:23	pop.gmail.com	Tx 'PASS password'
19.05.2015 16:41:25	pop.gmail.com	Rx '+OK Welcome.'
19.05.2015 16:41:25	pop.gmail.com	   Pop3MailClient Connection State Connected reached



Не получится это в лоб переделать и вот почему:
Вот начало общения imap.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
20.05.2015 15:46:31	imap.gmail.com	   Connect at port 993
20.05.2015 15:46:31	imap.gmail.com	   Get SSL connection
20.05.2015 15:46:31	imap.gmail.com	   Get SSL authentication
20.05.2015 15:46:31	imap.gmail.com	Rx '* OK Gimap ready for requests from 176.16.213.147 m9mb59377491ldr'
20.05.2015 15:46:31	imap.gmail.com	   Pop3MailClient Connection State Authorization reached
20.05.2015 15:46:31	imap.gmail.com	Tx '. LOGIN username@gmail.com password'
20.05.2015 15:46:32	imap.gmail.com	Rx '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT'
20.05.2015 15:46:32	imap.gmail.com	Rx '. OK username@gmail.com authenticated (Success)'
20.05.2015 15:46:32	imap.gmail.com	   Pop3MailClient Connection State Connected reached


Принципы общения разные.
pop: >команда <ответ
imap: >команда * отсебятина от сервера в любом месте <ответ

Т.е. код для pop3 базируется на методе
->pop3Stream.Write
<-response = pop3StreamReader.ReadLine()
(в крайнем случае несколько раз, но всегда знает сколько строк читать)

А в случае imap (принцип у него такой) сервер в любом месте может выдать строчку без тага (со звездочкой) типа выделенной Rx '* CAPABILITY IMAP4rev1
(в приведенном логе я искуственно прочитал лишнюю, отбросив ту что со звездочкой)

Как написано в документации, читать надо непрерывно (соответственно одним потоком и линейными функциями уже не отделаешься). Надо отдельно слать команды и независимо их читать (висеть на pop3StreamReader).
Но это как минимум полностью другая логика.
Т.е. для imap надо полностью разносить запись и чтение.
По принципу .ReadLine() висяк в любом месте с "error по таймауту" обеспечен.

В vb6 winsock насколько я помню как раз и висит
Код: vbnet
1.
Public Sub DataArrivalIMAP(Winsock1 As Winsock, ByVal bytesTotal As Long)


Antonariyфишка IMAP - нужно вести сквозную нумерацию отсылаемых команд (A1-A5)
Необязательно. Можешь точку ставить.
Фишка в том, что используя разные таги для разных команд, ты всегда (читая StreamReader) можешь понять что это ответ именно на твой конкретный запрос. Т.е. можешь накидать команд сразу, а он тебе даже не гарантирует что ответы вернутся в той же самой последовательности.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964410
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 Не получится это в лоб переделать и вот почему:Что-то я не понял твоей проблемы. В копипасте, что я дал, полный цикл IMAP-сеанса, который прекрасно работал бы, если бы не баг мэйлру с применением команд. Посмотри, как я там ответ в кучу собираю.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
        If Mid$(strData, InStr(strData, " ") + 1, 2) = "OK" Or Mid$(s(0), InStr(s(0), " ") + 1, 2) = "OK" Then
            'ответ закончился, разбираем, шлём новый запрос
        ElseIf InStr(strData, " NO ") = 0 And Mid$(s(0), 1, 1) = "*" Then
            'пришел кусок ответа, плюсуем его
            .BufferString = .BufferString & strData
        Else
            'вернулась ошибка
        End If



Дмитрий77 Принципы общения разные.
а процедуры у меня почти одинаковые почему-то. pop3 для сравнения:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Select Case m_States(Index).Protocol
        Case pSMTP: DataArrivalSMTP Winsock1(Index), bytesTotal
        Case pIMAP: DataArrivalIMAP Winsock1(Index), bytesTotal
    End Select
End Sub

Public Sub DataArrivalSMTP(Winsock1 As Winsock, ByVal bytesTotal As Long)
Dim m_oMessage As CMessage
Dim strData As String
Dim s As String
    On Error GoTo errh
    Winsock1.GetData strData
    With m_States(Winsock1.Index)
        'Debug.Print Winsock1.Index, strData
        If Left$(strData, 1) = "+" Or .State = POP3_TOP Or .State = POP3_RETR Then
            Select Case .State
                Case POP3_Connect
                    .MessagesCount = 0
                    .State = POP3_USER
                    Winsock1.SendData "USER " & .Login & vbCrLf
                Case POP3_USER
                    .State = POP3_PASS
                    Winsock1.SendData "PASS " & .Pass & vbCrLf
                Case POP3_PASS
                    .State = POP3_STAT
                    Winsock1.SendData "STAT" & vbCrLf
                    Debug.Print Winsock1.Index; ">STAT"
                Case POP3_STAT
                    .MessagesCount = CInt(Mid$(strData, 5, InStr(5, strData, " ") - 5))
                    If Not .StateStat Then
                        If .MessagesCount > 0 Then
                            .CurrentMsg = 1 '.MessagesCount
                            .MailCount = .MessagesCount
                            If FastMode Then
                                .State = POP3_TOP
                                Winsock1.SendData "TOP " & .CurrentMsg & " 0" & vbCrLf
                            Else
                                .State = POP3_RETR
                                Winsock1.SendData "RETR " & .CurrentMsg & vbCrLf
                            End If
                        Else
                            .MailCount = 0
                            .State = POP3_QUIT
                            Winsock1.SendData "QUIT" & vbCrLf
                        End If
                    Else
                        .State = POP3_QUIT
                        Winsock1.SendData "QUIT" & vbCrLf
                    End If
                Case POP3_TOP, POP3_RETR
                    .BufferString = .BufferString & strData
                    If InStr(1, .BufferString, vbLf & "." & vbCrLf) Then
                        If InStr(.BufferString, "+") = 1 Then .BufferString = Mid$(.BufferString, InStr(.BufferString, vbCrLf) + 2)
                        .BufferString = Left$(.BufferString, Len(.BufferString) - 3)
                        Set m_oMessage = New CMessage
                        m_oMessage.CreateFromText .BufferString
                        s = CheckMsg(m_oMessage, Winsock1.Index)
                        'Debug.Print Winsock1.Index, s
                        Winsock1.SendData s
                    End If
                Case POP3_QUIT
                    Winsock1.Close
                    .State = POP3_VeryQUIT
                Case POP3_DELE
                    .CurrentMsg = .CurrentMsg + 1
                    .BufferString = ""
                    If .CurrentMsg > .MessagesCount Then
                        .StateStat = True
                        .State = POP3_STAT
                        Winsock1.SendData "STAT" & vbCrLf
                    Else
                        If FastMode Then
                            .State = POP3_TOP
                            Winsock1.SendData "TOP " & .CurrentMsg & " 0" & vbCrLf
                        Else
                            .State = POP3_RETR
                            Winsock1.SendData "RETR " & .CurrentMsg & vbCrLf
                        End If
                    End If
            End Select
        Else
            Winsock1.SendData "QUIT" & vbCrLf
            .State = POP3_QUIT
            .Error = True
        End If
    End With
    Exit Sub
errh:
    With m_States(Winsock1.Index)
        frmReport.ctlProgress1.ErrDesc(Winsock1.Index) = LoadEnumString(, "ProgramError") & "DataArrivalSMTP - " & Err.Description
        Winsock1.Close
        Debug.Print Err.Description
        .State = POP3_VeryQUIT
        .Error = True
    End With
    Exit Sub
    Resume
End Sub

...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964439
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

Разница между приведенным мной кодом POP3 для .Net в том что у тебя

Код: vbnet
1.
2.
3.
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

End Sub



непрерывно (и "асинхронно") получает данные "как только так сразу" (событие).

А в моем .Net коде делается
pop3StreamReader.ReadLine() после команды
в том же потоке (предполагая что там должна быть строка, или несколько что для pop3 прогнозируемо, а для imap - нет).

Твой то конечно универсален для обоих случаев.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964527
carrotik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Antonariy,

Разница между приведенным мной кодом POP3 для .Net в том что у тебя

Код: vbnet
1.
2.
3.
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)

End Sub



непрерывно (и "асинхронно") получает данные "как только так сразу" (событие).

А в моем .Net коде делается
pop3StreamReader.ReadLine() после команды
в том же потоке (предполагая что там должна быть строка, или несколько что для pop3 прогнозируемо, а для imap - нет).

Твой то конечно универсален для обоих случаев.

...все там прогнозируемо, если посидеть с telnet-ом и покидать нужные команды на сервер :) ... у меня ReadLine вполне справляется, другое дело что требуется поработать над получаемой строкой, пообрезать всякие "OK FETCH COMPLETED" и т.д. .. в коде это выглядит некрасиво, но потом вполне съедобно .. но это если так уж сильно надо, простого рецепта "Взял и поехали" вероятно нет ...
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964581
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
carrotik,

ну это значит над каждой командой надо "сидеть индивидуально".
В pop3 коде - там немножко стандартизированный разбор (типа одна функция на несколько команд).
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964583
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потому что если сделаешь лишнюю ReadLine то по понятным причинам все нафиг зависнет.
А если сделаешь меньше чем надо, то не прочтешь ответ на запрос.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964598
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77потому что если сделаешь лишнюю ReadLine то по понятным причинам все нафиг зависнет.
А если сделаешь меньше чем надо, то не прочтешь ответ на запрос.
нехер инструментарий для хелловорда пользовать
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964744
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну я передумал сдаваться.
Уже понятно, что завелось.

Мне вот чего непонятно (я на эту тему вопрос задавал).
Письма, удаленные через IMAP на mail.ru получить по POP3 более невозможно. (корректно)
Письма, удаленные через IMAP на gmail.com по POP3 прекрасно потом выкачиваются (некорректно). При этом если слазить на gmail по web-интерфейсу, то после удаления по IMAP письмо из "входящих" перемещается в папку "вся почта".
В этой ситуации если клиент в моей проге настроит IMAP, а потом через месяц-другой перенастроит ее на POP3, то результат очевиден: прога повторно выкачает кучу уже давно принятого мыла. Бардак(с).

С точки зрения IMAP в обоих случаях удаленные по IMAP письма более недоступны.
После выкачки по POP3 по IMAP письма также более недоступны (в обоих случаях).


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
-------------------------
21.05.2015 6:01:15	imap.mail.ru	   Connect at port 993
21.05.2015 6:01:15	imap.mail.ru	   Get SSL connection
21.05.2015 6:01:15	imap.mail.ru	   Get SSL authentication
21.05.2015 6:01:15	imap.mail.ru	Rx '* OK Welcome'
21.05.2015 6:01:15	imap.mail.ru	   Pop3MailClient Connection State Authorization reached
21.05.2015 6:01:15	imap.mail.ru	Tx '. LOGIN username@bk.ru password'
21.05.2015 6:01:15	imap.mail.ru	Rx '* CAPABILITY IMAP4rev1 ID XLIST UIDPLUS UNSELECT MOVE'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK Authentication successful'
21.05.2015 6:01:15	imap.mail.ru	   Pop3MailClient Connection State Connected reached
21.05.2015 6:01:15	imap.mail.ru	Tx '. SELECT INBOX'
21.05.2015 6:01:15	imap.mail.ru	Rx '* FLAGS (\Answered \Flagged \Deleted \Draft \Seen)'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 1 EXISTS'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 0 RECENT'
21.05.2015 6:01:15	imap.mail.ru	Rx '* OK [UNSEEN 1]'
21.05.2015 6:01:15	imap.mail.ru	Rx '* OK [UIDVALIDITY 1363731524]'
21.05.2015 6:01:15	imap.mail.ru	Rx '* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft)]'
21.05.2015 6:01:15	imap.mail.ru	Rx '* OK [UIDNEXT 723]'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK [READ-WRITE] SELECT completed'
21.05.2015 6:01:15	imap.mail.ru	Tx '. FETCH 1 RFC822'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 1 FETCH (RFC822 {2452}'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK FETCH done'
21.05.2015 6:01:15	imap.mail.ru	   email with 73 lines,  2452 chars received
21.05.2015 6:01:15	imap.mail.ru	Tx '. STORE 1 +FLAGS (\DELETED)'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 1 FETCH (FLAGS (\Seen \Deleted))'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK STORE done'
21.05.2015 6:01:15	imap.mail.ru	Tx '. EXPUNGE'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 1 EXPUNGE'
21.05.2015 6:01:15	imap.mail.ru	Rx '* 0 EXISTS'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK EXPUNGE completed'
21.05.2015 6:01:15	imap.mail.ru	Tx '. LOGOUT'
21.05.2015 6:01:15	imap.mail.ru	Rx '* BYE logging out'
21.05.2015 6:01:15	imap.mail.ru	Rx '. OK LOGOUT completed'
21.05.2015 6:01:15	imap.mail.ru	   Pop3MailClient Connection State Closed reached


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
21.05.2015 6:08:11	imap.gmail.com	   Connect at port 993
21.05.2015 6:08:11	imap.gmail.com	   Get SSL connection
21.05.2015 6:08:11	imap.gmail.com	   Get SSL authentication
21.05.2015 6:08:11	imap.gmail.com	Rx '* OK Gimap ready for requests from 176.18.213.120 d70mb67149363lfd'
21.05.2015 6:08:11	imap.gmail.com	   Pop3MailClient Connection State Authorization reached
21.05.2015 6:08:11	imap.gmail.com	Tx '. LOGIN username@gmail.com password'
21.05.2015 6:08:12	imap.gmail.com	Rx '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE CONDSTORE ESEARCH UTF8=ACCEPT'
21.05.2015 6:08:12	imap.gmail.com	Rx '. OK faxvoip@gmail.com authenticated (Success)'
21.05.2015 6:08:12	imap.gmail.com	   Pop3MailClient Connection State Connected reached
21.05.2015 6:08:12	imap.gmail.com	Tx '. SELECT INBOX'
21.05.2015 6:08:12	imap.gmail.com	Rx '* FLAGS (\Answered \Flagged \Draft \Deleted \Seen $Phishing $NotPhishing)'
21.05.2015 6:08:12	imap.gmail.com	Rx '* OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen $Phishing $NotPhishing \*)] Flags permitted.'
21.05.2015 6:08:12	imap.gmail.com	Rx '* OK [UIDVALIDITY 612224604] UIDs valid.'
21.05.2015 6:08:12	imap.gmail.com	Rx '* 1 EXISTS'
21.05.2015 6:08:12	imap.gmail.com	Rx '* 0 RECENT'
21.05.2015 6:08:12	imap.gmail.com	Rx '* OK [UIDNEXT 5417] Predicted next UID.'
21.05.2015 6:08:12	imap.gmail.com	Rx '* OK [HIGHESTMODSEQ 538412]'
21.05.2015 6:08:12	imap.gmail.com	Rx '. OK [READ-WRITE] INBOX selected. (Success)'
21.05.2015 6:08:12	imap.gmail.com	Tx '. FETCH 1 RFC822'
21.05.2015 6:08:12	imap.gmail.com	Rx '* 1 FETCH (RFC822 {8769}'
21.05.2015 6:08:12	imap.gmail.com	Rx '. OK Success'
21.05.2015 6:08:12	imap.gmail.com	   email with 163 lines,  8769 chars received
21.05.2015 6:08:13	imap.gmail.com	Tx '. STORE 1 +FLAGS (\DELETED)'
21.05.2015 6:08:13	imap.gmail.com	Rx '* 1 FETCH (FLAGS (\Seen \Deleted))'
21.05.2015 6:08:13	imap.gmail.com	Rx '. OK Success'
21.05.2015 6:08:13	imap.gmail.com	Tx '. EXPUNGE'
21.05.2015 6:08:13	imap.gmail.com	Rx '* 1 EXPUNGE'
21.05.2015 6:08:13	imap.gmail.com	Rx '* 0 EXISTS'
21.05.2015 6:08:13	imap.gmail.com	Rx '. OK Success'
21.05.2015 6:08:13	imap.gmail.com	Tx '. LOGOUT'
21.05.2015 6:08:13	imap.gmail.com	Rx '* BYE LOGOUT Requested'
21.05.2015 6:08:13	imap.gmail.com	Rx '. OK 73 good day (Success)'
21.05.2015 6:08:13	imap.gmail.com	   Pop3MailClient Connection State Closed reached



P.S. Коды пока настолько неэстетично выглядят, что пока выкладывать не буду.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964811
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот допустим есть 4 письма (нумерация по id тек. сессии а не по uid):
1-2-3-4
В какой последовательности надо забирать, чтоб самое старое забрать первым?
с головы 1-2-3-4 ?
или с хвоста? 4-3-2-1 ?
Для pop3? Для imap?
Я беру 1-2-3-4 но возникли сомнения?

Antonariyна mail.ru, а там был то ли баг, то ли фича: команда, имеющая параметром значение , применялась к двум сообщениям, заданному и следующему. а если сообщение одно или последнее, то все ок. мэйлру вопрос о том, что за ерунда творится, проигнорировало. по факту IMAP мне не был нужен, я и забил на него совсем.
не подтверждаю
4 письма скачались и удалились:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
. FETCH 1 RFC822
. STORE 1 +FLAGS (\DELETED)
. FETCH 2 RFC822
. STORE 2 +FLAGS (\DELETED)
. FETCH 3 RFC822
. STORE 3 +FLAGS (\DELETED)
. FETCH 4 RFC822
. STORE 4 +FLAGS (\DELETED)
. EXPUNGE
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964839
carrotik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А вот допустим есть 4 письма (нумерация по id тек. сессии а не по uid):
1-2-3-4
В какой последовательности надо забирать, чтоб самое старое забрать первым?
с головы 1-2-3-4 ?
или с хвоста? 4-3-2-1 ?
Для pop3? Для imap?
Я беру 1-2-3-4 но возникли сомнения?


.. я уже говорил, у IMAP-a есть команда SEARCH - там можно выбирать по разным параметрам,
вот тут
.. полагаться на сквозную нумерацию я бы не стал ...
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38964908
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
carrotikДмитрий77Я беру 1-2-3-4 но возникли сомнения?
полагаться на сквозную нумерацию я бы не стал ...
Да не, вроде правильно делаю.
авторMessage Sequence Number Message Attribute

A relative position from 1 to the number of messages in the mailbox.
This position MUST be ordered by ascending unique identifier . As
each new message is added, it is assigned a message sequence number
that is 1 higher than the number of messages in the mailbox before
that new message was added.


Unique Identifier (UID) Message Attribute

Unique identifiers
are assigned in a strictly ascending fashion in the mailbox ; as each
message is added to the mailbox it is assigned a higher UID than the
message(s) which were added previously.

проверил
1-2-3-4
5645-5646-5647-5648

т.е. порядок Sequence соответствует порядку Unique, и порядок этот возрастающий.
И в той же последовательности 1-2-3-4 скачивает pop3
1-самое старое 4 -самое новое
понятно что если пришли почти одновременно то могут чуть перепутаться с т.зр. времени их отправки и т.п. Но очередь получения сервером (добавления в папку) здесь соблюдена.
Что мне важно, чтобы при возникновении очереди новые "задания" не лезли сильно вперед "старых", обработаны они будут в той же последовательности что и скачаны.
Но на самом деле при интервале проверки писем 20 сек об этом можно вообще не заморачиваться.

Но рассчитывать можно. А search это сложности и излишки и еще непонятно чего она там насортирует в зависимости от фантазии вопрошающего.
...
Рейтинг: 0 / 0
А про IMAP не разжуете?
    #38965858
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, собственно конечный допиленный результат (полный код под спойлером внизу).
Тестировал с gmail.com, Hotmail.com, mail.ru (ssl,993) и с агавой по 143 порту.
Ошибок в работе не замечено (кроме того что gmail после удаления по IMAP оставляет письма в POP3, но только gmail).

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
  Public Sub GetMailImap(ByVal m_ImapServer As String, ByVal m_User As String, ByVal m_Password As String, _
   Optional ByVal m_ServerPort As Integer = 143, Optional ByVal m_useSSL As Boolean = False, _
   Optional ByVal m_DeleteEmails As Boolean = True, Optional ByVal m_SaveDir As String = vbNullString, _
   Optional ByVal m_SaveMailPrefix As String = "MSG", Optional ByVal m_SaveMailExt As String = ".eml", _
   Optional ByVal m_TraceFunction As Imap.TraceHandler = Nothing, Optional ByVal m_TestMode As Boolean = False)

     Try
      ' prepare Imap client
      Dim ImapClient As Imap.cImapMailClient = _
       New Imap.cImapMailClient(m_ImapServer, m_ServerPort, m_useSSL, m_User, m_Password)
      ImapClient.IsAutoReconnect = True

      'if tracing needed
      If m_TraceFunction IsNot Nothing Then AddHandler ImapClient.Trace, m_TraceFunction

      ImapClient.ReadTimeout = 60000 'give Imap server 60 seconds to answer

      'establish connection
      ImapClient.Connect()

      'select inbox
      Dim NumberOfMails As Integer = 0
      If ImapClient.SelectMailbox("INBOX", NumberOfMails) Then

        If m_TestMode Then

          'only show info
          If NumberOfMails > 0 Then
            For i As Integer = 1 To NumberOfMails
              'get Unique Email Id
              Dim UniqueEmailId As Integer
              ImapClient.GetUniqueEmailId(i, UniqueEmailId)

              'get email size
              Dim EmailSize As Integer
              ImapClient.GetEmailSize(i, EmailSize)
            Next
          End If

          'ping server
          ImapClient.NOOP()

        Else

          'get emails
          If NumberOfMails > 0 Then

            If Strings.Len(m_SaveDir) = 0 OrElse IO.Directory.Exists(m_SaveDir) = False Then _
             m_SaveDir = My.Application.Info.DirectoryPath
            If Strings.Len(m_SaveMailPrefix) = 0 Then m_SaveMailPrefix = "MSG"
            If Strings.Len(m_SaveMailExt) = 0 Then m_SaveMailExt = ".eml"
            If Strings.Left(m_SaveMailExt, 1) <> "." Then m_SaveMailExt = "." & m_SaveMailExt

            For i As Integer = 1 To NumberOfMails

              'get email
              Dim Email As String = ""
              ImapClient.GetRawEmail(i, Email)
              If Strings.Len(Email) > 0 Then
                Dim fToSave As String = GetNextEmailFileName(m_SaveDir, m_SaveMailPrefix, m_SaveMailExt)
                Try : IO.File.WriteAllText(fToSave, Email, System.Text.Encoding.ASCII) : Catch : End Try
              End If

              'delete email
              If m_DeleteEmails Then ImapClient.DeleteEmail(i)
            Next
            If m_DeleteEmails Then ImapClient.Expunge()
          End If

        End If

      End If

      'close connection
      ImapClient.Disconnect()

    Catch ex As Exception
      If m_TraceFunction IsNot Nothing Then
        m_TraceFunction("Run Time Error Occured:")
        m_TraceFunction(ex.Message)
        m_TraceFunction(ex.StackTrace)
      End If
    End Try

  End Sub




Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
Imports System.Net.Sockets
Imports System.Net.Security
Imports System.IO
Imports System.Text

Module ModuleImap

  Public Sub GetMailImap(ByVal m_ImapServer As String, ByVal m_User As String, ByVal m_Password As String, _
   Optional ByVal m_ServerPort As Integer = 143, Optional ByVal m_useSSL As Boolean = False, _
   Optional ByVal m_DeleteEmails As Boolean = True, Optional ByVal m_SaveDir As String = vbNullString, _
   Optional ByVal m_SaveMailPrefix As String = "MSG", Optional ByVal m_SaveMailExt As String = ".eml", _
   Optional ByVal m_TraceFunction As Imap.TraceHandler = Nothing, Optional ByVal m_TestMode As Boolean = False)

    If m_TraceFunction IsNot Nothing AndAlso m_TestMode = False Then m_TraceFunction("-------------------------")
    Try
      ' prepare Imap client
      Dim ImapClient As Imap.cImapMailClient = _
       New Imap.cImapMailClient(m_ImapServer, m_ServerPort, m_useSSL, m_User, m_Password)
      ImapClient.IsAutoReconnect = True

      'if tracing needed
      If m_TraceFunction IsNot Nothing Then AddHandler ImapClient.Trace, m_TraceFunction

      ImapClient.ReadTimeout = 60000 'give Imap server 60 seconds to answer

      'establish connection
      ImapClient.Connect()

      'select inbox
      Dim NumberOfMails As Integer = 0
      If ImapClient.SelectMailbox("INBOX", NumberOfMails) Then

        If m_TestMode Then

          'only show info
          If NumberOfMails > 0 Then
            For i As Integer = 1 To NumberOfMails
              'get Unique Email Id
              Dim UniqueEmailId As Integer
              ImapClient.GetUniqueEmailId(i, UniqueEmailId)

              'get email size
              Dim EmailSize As Integer
              ImapClient.GetEmailSize(i, EmailSize)
            Next
          End If

          'ping server
          ImapClient.NOOP()

        Else

          'get emails
          If NumberOfMails > 0 Then

            If Strings.Len(m_SaveDir) = 0 OrElse IO.Directory.Exists(m_SaveDir) = False Then _
             m_SaveDir = My.Application.Info.DirectoryPath
            If Strings.Len(m_SaveMailPrefix) = 0 Then m_SaveMailPrefix = "MSG"
            If Strings.Len(m_SaveMailExt) = 0 Then m_SaveMailExt = ".eml"
            If Strings.Left(m_SaveMailExt, 1) <> "." Then m_SaveMailExt = "." & m_SaveMailExt

            For i As Integer = 1 To NumberOfMails

              '===не надо этого здесь, это время, сравнимое со скачиванием!!! ===
              ''get Unique Email Id
              'Dim UniqueEmailId As Integer
              'ImapClient.GetUniqueEmailId(i, UniqueEmailId)

              ''get email size
              'Dim EmailSize As Integer
              'ImapClient.GetEmailSize(i, EmailSize)
              '===не надо этого здесь, это время!!! ===

              'get email
              Dim Email As String = ""
              ImapClient.GetRawEmail(i, Email)
              If Strings.Len(Email) > 0 Then
                Dim fToSave As String = GetNextEmailFileName(m_SaveDir, m_SaveMailPrefix, m_SaveMailExt)
                Try : IO.File.WriteAllText(fToSave, Email, System.Text.Encoding.ASCII) : Catch : End Try
              End If

              'delete email
              If m_DeleteEmails Then ImapClient.DeleteEmail(i)
            Next
            If m_DeleteEmails Then ImapClient.Expunge()
          End If

        End If

      End If

      'close connection
      ImapClient.Disconnect()

    Catch ex As Exception
      If m_TraceFunction IsNot Nothing Then
        m_TraceFunction("Run Time Error Occured:")
        m_TraceFunction(ex.Message)
        m_TraceFunction(ex.StackTrace)
      End If
    End Try
    If m_TraceFunction IsNot Nothing AndAlso m_TestMode = False Then m_TraceFunction("-------------------------")

  End Sub

  Private Function GetNextEmailFileName(ByVal path As String, ByVal pref As String, ByVal ext As String) As String
    Dim tmp_name As String
    Dim i As Integer = 0
    Do
      i = i + 1
      tmp_name = IO.Path.Combine(path, pref & i.ToString & ext)
      If IO.File.Exists(tmp_name) = False Then Return tmp_name
    Loop
  End Function

End Module

Namespace Imap
  ' Supporting classes and structs
  ' ==============================

  ''' <summary>
  ''' Combines Email ID with Email UID for one email
  ''' The Imap server assigns to each message a unique Email UID, which will not change for the life time
  ''' of the message and no other message should use the same.
  ''' 
  ''' Exceptions:
  ''' Throws ImapException if there is a serious communication problem with the Imap server, otherwise
  ''' 
  ''' </summary>
  Public Structure EmailUid
    ''' <summary>
    ''' used in IMAP commands to indicate which message (only valid in the present session)
    ''' </summary>
    Public EmailId As Integer
    ''' <summary>
    ''' Uid is always the same for a message, regardless of session
    ''' </summary>
    Public Uid As String

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="EmailId"></param>
    ''' <param name="Uid"></param>
    Public Sub New(ByVal EmailId As Integer, ByVal Uid As String)
      Me.EmailId = EmailId
      Me.Uid = Uid
    End Sub
  End Structure

  ''' <summary>
  ''' If anything goes wrong within ImapMailClient, an ImapException is raised
  ''' </summary>
  Public Class ImapException
    Inherits ApplicationException
    ''' <summary>
    ''' 
    ''' </summary>
    Public Sub New()
    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="ErrorMessage"></param>
    Public Sub New(ByVal ErrorMessage As String)
      MyBase.New(ErrorMessage)
    End Sub
  End Class

  ''' <summary>
  ''' An Imap connection goes through the following states:
  ''' </summary>
  Public Enum ImapConnectionStateEnum
    ''' <summary>
    ''' undefined
    ''' </summary>
    None = 0
    ''' <summary>
    ''' not connected yet to Imap server
    ''' </summary>
    Disconnected
    ''' <summary>
    ''' TCP connection has been opened and the Imap server has sent the greeting. Imap server expects user name and password
    ''' </summary>
    Authorization
    ''' <summary>
    ''' client has identified itself successfully with the IMAP, server has locked all messages 
    ''' </summary>
    Connected
    ''' <summary>
    ''' LOGOUT command was sent, the server has released the resources
    ''' </summary>
    Closed
  End Enum

  ' Delegates for ImapMailClient
  ' ============================

  ''' <summary>
  ''' If IMAP Server doesn't react as expected or this code has a problem, but
  ''' can continue with the execution, a Warning is called.
  ''' </summary>
  ''' <param name="WarningText"></param>
  ''' <param name="Response">string received from IMAP server</param>
  Public Delegate Sub WarningHandler(ByVal WarningText As String, ByVal Response As String)

  ''' <summary>
  ''' Traces all the information exchanged between IMAP client and IMAP server plus some
  ''' status messages from IMAP client.
  ''' Helpful to investigate any problem.
  ''' Console.WriteLine() can be used
  ''' </summary>
  ''' <param name="TraceText"></param>
  Public Delegate Sub TraceHandler(ByVal TraceText As String)

  ' cImapMailClient
  ' ====================  

  ''' <summary>
  ''' provides access to emails on an IMAP Server
  ''' </summary>
  Public Class cImapMailClient

    'Events
    '------

    ''' <summary>
    ''' Called whenever IMAP server doesn't react as expected, but no runtime error is thrown.
    ''' </summary>
    Public Event Warning As WarningHandler

    ''' <summary>
    ''' call warning event
    ''' </summary>
    ''' <param name="methodName">name of the method where warning is needed</param>
    ''' <param name="response">answer from IMAP server causing the warning</param>
    ''' <param name="warningText">explanation what went wrong</param>
    ''' <param name="warningParameters"></param>
    Protected Sub CallWarning(ByVal methodName As String, ByVal response As String, _
     ByVal warningText As String, ByVal ParamArray warningParameters As Object())
      warningText = String.Format(warningText, warningParameters)
      RaiseEvent Warning(Convert.ToString(methodName & Convert.ToString(": ")) & warningText, response)
      CallTrace("!! {0}", warningText)
    End Sub

    ''' <summary>
    ''' Shows the communication between ImapClient and ImapServer, including warnings
    ''' </summary>
    Public Event Trace As TraceHandler

    ''' <summary>
    ''' call Trace event
    ''' </summary>
    ''' <param name="text">string to be traced</param>
    ''' <param name="parameters"></param>
    Protected Sub CallTrace(ByVal text As String, ByVal ParamArray parameters As Object())
      'RaiseEvent Trace(DateTime.Now.ToString("hh:mm:ss ") + m_ImapServer + " " + String.Format(text, parameters))
      RaiseEvent Trace(DateTime.Now.ToString + Chr(9) + m_ImapServer + Chr(9) + String.Format(text, parameters))
    End Sub

    ''' <summary>
    ''' Trace information received from IMAP server
    ''' </summary>
    ''' <param name="text">string to be traced</param>
    ''' <param name="parameters"></param>
    Protected Sub TraceFrom(ByVal text As String, ByVal ParamArray parameters As Object())
      CallTrace("   " + String.Format(text, parameters))
    End Sub

    'Properties
    '------

    ''' <summary>
    ''' Get IMAP server name
    ''' </summary>
    Public ReadOnly Property ImapServer() As String
      Get
        Return m_ImapServer
      End Get
    End Property
    ''' <summary>
    ''' IMAP server name
    ''' </summary>
    Protected m_ImapServer As String

    ''' <summary>
    ''' Get IMAP server port
    ''' </summary>
    Public ReadOnly Property Port() As Integer
      Get
        Return m_port
      End Get
    End Property
    ''' <summary>
    ''' POP3 server port
    ''' </summary>
    Protected m_port As Integer

    ''' <summary>
    ''' Should SSL be used for connection with IMAP server ?
    ''' </summary>
    Public ReadOnly Property UseSSL() As Boolean
      Get
        Return m_useSSL
      End Get
    End Property
    ''' <summary>
    ''' Should SSL be used for connection with IMAP server ?
    ''' </summary>
    Private m_useSSL As Boolean

    ''' <summary>
    ''' should ImapMailClient automatically reconnect if IMAP server has dropped the 
    ''' connection due to a timeout ?
    ''' </summary>
    Public Property IsAutoReconnect() As Boolean
      Get
        Return m_isAutoReconnect
      End Get
      Set(ByVal value As Boolean)
        m_isAutoReconnect = value
      End Set
    End Property
    Private m_isAutoReconnect As Boolean = False
    'timeout has occured, we try to perform an autoreconnect
    Private isTimeoutReconnect As Boolean = False

    ''' <summary>
    ''' Get / set read timeout (miliseconds)
    ''' </summary>
    Public Property ReadTimeout() As Integer
      Get
        Return m_readTimeout
      End Get
      Set(ByVal value As Integer)
        m_readTimeout = value
        If ImapStream IsNot Nothing AndAlso ImapStream.CanTimeout Then
          ImapStream.ReadTimeout = m_readTimeout
        End If
      End Set
    End Property
    ''' <summary>
    ''' IMAP server read timeout
    ''' </summary>
    Protected m_readTimeout As Integer = -1

    ''' <summary>
    ''' Get owner name of mailbox on IMAP server
    ''' </summary>
    Public ReadOnly Property Username() As String
      Get
        Return m_username
      End Get
    End Property
    ''' <summary>
    ''' Owner name of mailbox on IMAP server
    ''' </summary>
    Protected m_username As String

    ''' <summary>
    ''' Get password for mailbox on IMAP server
    ''' </summary>
    Public ReadOnly Property Password() As String
      Get
        Return m_password
      End Get
    End Property
    ''' <summary>
    ''' Password for mailbox on IMAP server
    ''' </summary>
    Protected m_password As String

    ''' <summary>
    ''' Get connection status with IMAP server
    ''' </summary>
    Public ReadOnly Property ImapConnectionState() As ImapConnectionStateEnum
      Get
        Return m_ImapConnectionState
      End Get
    End Property
    ''' <summary>
    ''' connection status with IMAP server
    ''' </summary>
    Protected m_ImapConnectionState As ImapConnectionStateEnum = ImapConnectionStateEnum.Disconnected

    ' Methods
    ' -------

    ''' <summary>
    ''' set IMAP connection state
    ''' </summary>
    ''' <param name="State"></param>
    Protected Sub setImapConnectionState(ByVal State As ImapConnectionStateEnum)
      m_ImapConnectionState = State
      CallTrace("   ImapMailClient Connection State {0} reached", State)
    End Sub

    ''' <summary>
    ''' throw exception if IMAP connection is not in the required state
    ''' </summary>
    ''' <param name="requiredState"></param>
    Protected Sub EnsureState(ByVal requiredState As ImapConnectionStateEnum)
      If m_ImapConnectionState <> requiredState Then
        ' wrong connection state
        Throw New ImapException("This command only accepted during connection state: " + requiredState.ToString() + _
         vbLf & " The connection to server " + m_ImapServer + " is in state " + m_ImapConnectionState.ToString())
      End If
    End Sub

    'private fields
    '--------------
    ''' <summary>
    ''' TCP to IMAP server
    ''' </summary>
    Private serverTcpConnection As TcpClient
    ''' <summary>
    ''' Stream from IMAP server with or without SSL
    ''' </summary>
    Private ImapStream As Stream
    ''' <summary>
    ''' Reader for IMAP message
    ''' </summary>
    Protected ImapStreamReader As StreamReader
    ''' <summary>
    ''' char 'array' for carriage return / line feed
    ''' </summary>
    Protected CRLF As String = vbCr & vbLf

    'public methods
    '--------------

    ''' <summary>
    ''' Make IMAP client ready to connect to IMAP server
    ''' </summary>
    ''' <param name="ImapServer"><example>imap.gmail.com</example></param>
    ''' <param name="Port"><example>993</example></param>
    ''' <param name="useSSL">True: SSL is used for connection to IMAP server</param>
    ''' <param name="Username"><example>abc@gmail.com<;/example></param>
    ''' <param name="Password">Secret</param>
    Public Sub New(ByVal ImapServer As String, ByVal Port As Integer, ByVal useSSL As Boolean, _
     ByVal Username As String, ByVal Password As String)
      Me.m_ImapServer = ImapServer
      Me.m_port = Port
      Me.m_useSSL = useSSL
      Me.m_username = Username
      Me.m_password = Password
    End Sub

    ''' <summary>
    ''' Connect to IMAP server
    ''' </summary>
    Public Sub Connect()
      If (m_ImapConnectionState <> ImapConnectionStateEnum.Disconnected) AndAlso
       (m_ImapConnectionState <> ImapConnectionStateEnum.Closed) AndAlso
       (Not isTimeoutReconnect) Then
        CallWarning("connect", "", "Connect command received, but connection state is: " + m_ImapConnectionState.ToString())
      Else
        'establish TCP connection
        Try
          CallTrace("   Connect at port {0}", m_port)
          serverTcpConnection = New TcpClient(m_ImapServer, m_port)
        Catch ex As Exception
          Throw New ImapException("Connection to server " + m_ImapServer + ", port " + m_port.ToString + " failed." & vbCrLf & "Runtime Error: " + ex.ToString())
        End Try

        If m_useSSL Then
          'get SSL stream
          Try
            CallTrace("   Get SSL connection")
            ImapStream = New SslStream(serverTcpConnection.GetStream(), False)
            ImapStream.ReadTimeout = m_readTimeout
          Catch ex As Exception
            Throw New ImapException("Server " + m_ImapServer + " found, but cannot get SSL data stream." & vbCrLf & "Runtime Error: " + ex.ToString())
          End Try

          'perform SSL authentication
          Try
            CallTrace("   Get SSL authentication")
            DirectCast(ImapStream, SslStream).AuthenticateAsClient(m_ImapServer)
          Catch ex As Exception
            Throw New ImapException("Server " + m_ImapServer + " found, but problem with SSL Authentication." & vbCrLf & "Runtime Error: " + ex.ToString())
          End Try
        Else
          'create a stream to IMAP server without using SSL
          Try
            CallTrace("   Get connection without SSL")
            ImapStream = serverTcpConnection.GetStream()
            ImapStream.ReadTimeout = m_readTimeout
          Catch ex As Exception
            Throw New ImapException("Server " + m_ImapServer + " found, but cannot get data stream (without SSL)." & vbCrLf & "Runtime Error: " + ex.ToString())
          End Try
        End If

        'get stream for reading from pop server
        'POP3 allows only US-ASCII. The message will be translated in the proper encoding in a later step
        Try
          ImapStreamReader = New StreamReader(ImapStream, Encoding.ASCII)
        Catch ex As Exception
          If m_useSSL Then
            Throw New ImapException("Server " + m_ImapServer + " found, but cannot read from SSL stream." & vbCrLf & "Runtime Error: " + ex.ToString())
          Else
            Throw New ImapException("Server " + m_ImapServer + " found, but cannot read from stream (without SSL)." & vbCrLf & "Runtime Error: " + ex.ToString())
          End If
        End Try

        'ready for authorisation
        Dim response As String = ""
        If Not readSingleLine(response) Then
          Throw New ImapException(Convert.ToString("Server " + m_ImapServer + " not ready to start AUTHORIZATION." & vbCrLf & "Message: ") & response)
        End If
        setImapConnectionState(ImapConnectionStateEnum.Authorization)

        'send user name
        If Not executeCommand("LOGIN " + m_username + " " + m_password, response) Then
          Throw New ImapException(Convert.ToString("Server " + m_ImapServer + " doesn't accept username '" + m_username + "' and password '" + m_password + "'." & vbCrLf & "Message: ") & response)
        End If

        setImapConnectionState(ImapConnectionStateEnum.Connected)
      End If
    End Sub

    ''' <summary>
    ''' Disconnect from IMAP Server
    ''' </summary>
    Public Sub Disconnect()
      If m_ImapConnectionState = ImapConnectionStateEnum.Disconnected OrElse _
       m_ImapConnectionState = ImapConnectionStateEnum.Closed Then
        CallWarning("disconnect", "", "Disconnect received, but was already disconnected.")
      Else
        'ask server to end session and possibly to remove emails marked for deletion
        Try
          Dim response As String = ""
          If executeCommand("LOGOUT", response) Then
            'server says everything is ok
            setImapConnectionState(ImapConnectionStateEnum.Closed)
          Else
            'server says there is a problem
            CallWarning("Disconnect", response, Convert.ToString("negative response from server while closing connection: ") & response)
            setImapConnectionState(ImapConnectionStateEnum.Disconnected)
          End If
        Finally
          'close connection
          If ImapStream IsNot Nothing Then
            ImapStream.Close()
          End If

          ImapStreamReader.Close()
        End Try
      End If
    End Sub

    ''' <summary>
    ''' Selects a mailbox so that messages in the mailbox can be accessed
    ''' </summary>
    ''' <param name="MailboxFolder">mailbox name, usually INBOX</param>
    ''' <param name="NumberOfMails">Return the number of messages in the mailbox</param>
    ''' <returns></returns>
    Public Function SelectMailbox(ByVal MailboxFolder As String, ByRef NumberOfMails As Integer) As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)

      'read response from server
      Dim response As String = ""
      Dim responses As New Collection 'все строки, а не только крайняя которая с тагом
      If Not executeCommand("SELECT " & MailboxFolder, response, , responses) Then
        CallWarning("SelectMailbox", response, "failed to select " & MailboxFolder & " folder")
        Return False
      End If
      For Each s As String In responses
        If (s.Length > 0) AndAlso s(0) = "*"c Then
          If InStr(UCase(s), "EXISTS") > 0 Then
            ' Rx '* 0 EXISTS'
            NumberOfMails = CType(Val(Split(s, "*")(1)), Integer)
            Exit For
          End If
        End If
      Next
      Return True
    End Function

    ''' <summary>
    ''' Delete message from server.
    ''' Flag is set on the message marking it as deleted. This, by itself, 
    ''' does nothing to get the message removed. Just when a special 
    ''' command is called all messages in the current folder marked 
    ''' as to be deleted are removed.
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <returns></returns>
    Public Function DeleteEmail(ByVal msg_number As Integer) As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)
      Dim response As String = ""
      If Not executeCommand("STORE " + msg_number.ToString() + " +FLAGS (\DELETED)", response) Then
        CallWarning("DeleteEmail", response, "negative response for email (Id: {0}) delete request", msg_number)
        Return False
      End If
      Return True
    End Function

    ''' <summary>
    ''' The EXPUNGE command permanently removes all messages that have the
    ''' \Deleted flag set from the currently selected mailbox. Before
    ''' returning an OK to the client, an untagged EXPUNGE response is
    ''' sent for each message that is removed.
    ''' </summary>
    ''' <returns></returns>
    Public Function Expunge() As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)
      Dim response As String = ""
      Return executeCommand("EXPUNGE", response)
    End Function

    ''' <summary>
    ''' get size of one particular email
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <param name="EmailSize"></param>
    ''' <returns></returns>
    Public Function GetEmailSize(ByVal msg_number As Integer, ByRef EmailSize As Integer) As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)
      Dim response As String = ""
      Dim responses As New Collection
      If executeCommand("FETCH " + msg_number.ToString() + " RFC822.SIZE", response, , responses) = False Then Return False

      For Each s As String In responses
        If (s.Length > 0) AndAlso (s(0) = "*"c) Then
          If InStr(UCase(s), "FETCH") > 0 AndAlso InStr(UCase(s), "RFC822.SIZE") > 0 _
           AndAlso InStr(s, "(") > 0 AndAlso InStr(s, ")") > 0 Then
            'Rx '* 1 FETCH (RFC822.SIZE 43534)'
            EmailSize = CType(Val(Strings.Right(s, Strings.Len(s) - InStr(UCase(s), "RFC822.SIZE") - 10)), Integer)
            Return True
          End If
        End If
      Next
      Return False
    End Function

    ''' <summary>
    ''' get Unique Email Id
    ''' </summary>
    ''' <param name="msg_number"></param>
    ''' <param name="UniqueEmailId"></param>
    ''' <returns></returns>
    Public Function GetUniqueEmailId(ByVal msg_number As Integer, ByRef UniqueEmailId As Integer) As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)
      Dim response As String = ""
      Dim responses As New Collection
      If executeCommand("FETCH " + msg_number.ToString() + " UID", response, , responses) = False Then Return False

      For Each s As String In responses
        If (s.Length > 0) AndAlso (s(0) = "*"c) Then
          If InStr(UCase(s), "FETCH") > 0 AndAlso InStr(UCase(s), "UID") > 0 _
           AndAlso InStr(s, "(") > 0 AndAlso InStr(s, ")") > 0 Then
            'Rx '* 1 FETCH (UID 5449)'
            UniqueEmailId = CType(Val(Strings.Right(s, Strings.Len(s) - InStr(UCase(s), "UID") - 2)), Integer)
            Return True
          End If
        End If
      Next
      Return False
    End Function

    ''' <summary>
    ''' Sends an 'empty' command to the IMAP server. Server has to respond with OK
    ''' </summary>
    ''' <returns>true: server responds as expected</returns>
    Public Function NOOP() As Boolean
      EnsureState(ImapConnectionStateEnum.Connected)
      Dim response As String = ""
      If Not executeCommand("NOOP", response) Then
        CallWarning("NOOP", response, "negative response for NOOP request")
        Return False
      End If
      Return True
    End Function

    ''' <summary>
    ''' Should the raw content, the US-ASCII code as received, be traced
    ''' GetRawEmail will switch it on when it starts and off once finished
    ''' 
    ''' Inheritors might use it to get the raw email
    ''' </summary>
    Protected isTraceRawEmail As Boolean = False


    ''' <summary>
    ''' contains one MIME part of the email in US-ASCII, needs to be translated in .NET string (Unicode)
    ''' contains the complete email in US-ASCII, needs to be translated in .NET string (Unicode)
    ''' For speed reasons, reuse StringBuilder
    ''' </summary>
    Protected RawEmailSB As StringBuilder

    ''' <summary>
    ''' Reads the complete text of a message
    ''' </summary>
    ''' <param name="MessageNo">Email to retrieve</param>
    ''' <param name="EmailText">ASCII string of complete message</param>
    ''' <returns></returns>
    Public Function GetRawEmail(ByVal MessageNo As Integer, ByRef EmailText As String) As Boolean
      'send 'FETCH int RFC822' command to server
      EnsureState(ImapConnectionStateEnum.Connected)

      'read response from server
      Dim response As String = ""
      Dim responses As New Collection 'все строки, а не только крайняя которая с тагом
      ' retrieve mail with message number
      If Not executeCommand("FETCH " + MessageNo.ToString() + " RFC822", response, , responses) Then
        CallWarning("GetRawEmail", response, "failed to retrieve mail with message number " & MessageNo.ToString())
        Return False
      End If

      Dim elenth As Integer 'длина e-mail

      'get the lines
      Dim LineCounter As Integer = 0
      'empty StringBuilder
      If RawEmailSB Is Nothing Then
        RawEmailSB = New StringBuilder(100000)
      Else
        RawEmailSB.Length = 0
      End If
      Dim ReadRawEmail As Boolean = False
      For Each raw As String In responses
        If ReadRawEmail Then
          If raw.Length > 0 AndAlso raw(0) = "."c Then 'it is the last line
            EmailText = Strings.Left(RawEmailSB.ToString(), elenth) 'обрезаем сообщенным количеством символов
            TraceFrom("email with {0} lines,  {1} chars received", LineCounter.ToString(), EmailText.Length)
            Return True
          Else
            'collect all responses as received
            RawEmailSB.Append(raw & CRLF)
            LineCounter += 1
          End If
        Else
          If (raw.Length > 0) AndAlso (raw(0) = "*"c) Then
            If InStr(UCase(raw), "FETCH") > 0 AndAlso InStr(UCase(raw), "RFC822") > 0 _
             AndAlso InStr(raw, "{") > 0 AndAlso InStr(raw, "}") > 0 Then
              'Rx '* 1 FETCH (RFC822 {8769}'
              elenth = CType(Val(Split(Split(raw, "{")(1), "}")(0)), Integer)
              ReadRawEmail = True
            End If
          End If
        End If
      Next
      Return False
    End Function

    'Helper methodes
    '---------------

    Public isDebug As Boolean = False

    ''' <summary>
    ''' sends the command to IMAP server (adds CRLF) and waits for the
    ''' response of the server
    ''' </summary>
    ''' <param name="command">command to be sent to server</param>
    ''' <param name="response">final tagged answer from server</param>
    ''' <param name="tag">tag chosen by the client </param>
    ''' <param name="responses">collection of all answers from server</param>
    ''' <returns>false: server sent negative acknowledge, i.e. server could not execute command</returns>
    Private Function executeCommand(ByVal command As String, ByRef response As String, _
     Optional ByVal tag As String = ".", Optional ByRef responses As Collection = Nothing) As Boolean
      If Strings.Len(tag) = 0 Then tag = "."
      'send command to server
      Dim commandBytes As Byte() = System.Text.Encoding.ASCII.GetBytes((tag & " " & command & CRLF).ToCharArray())
      CallTrace("Tx '{0}'", tag & " " & command)
      Dim isSupressThrow As Boolean = False
      Try
        ImapStream.Write(commandBytes, 0, commandBytes.Length)
        If isDebug Then
          isDebug = False
          Throw New IOException("Test", New SocketException(10053))
        End If
      Catch ex As IOException
        'Unable to write data to the transport connection. Check if reconnection should be tried
        isSupressThrow = executeReconnect(ex, command, commandBytes, tag)
        If Not isSupressThrow Then
          Throw
        End If
      End Try
      ImapStream.Flush()

      'read response from server
      response = Nothing
      Do
        Try
          response = ImapStreamReader.ReadLine()
        Catch ex As IOException
          'Unable to write data to the transport connection. Check if reconnection should be tried
          isSupressThrow = executeReconnect(ex, command, commandBytes, tag)
          If isSupressThrow Then
            'wait for response one more time
            response = ImapStreamReader.ReadLine()
          Else
            Throw
          End If
        End Try
        If response Is Nothing Then
          Throw New ImapException("Server " + m_ImapServer + " has not responded, timeout has occured.")
        End If
        If responses IsNot Nothing Then responses.Add(response)
        If Strings.Left(response, 2) = "* " Then 'фактически все ответы приходят со * 
          CallTrace("Rx '{0}'", response) '(если без * ,данные мыла, то не надо это все выводить)
        ElseIf Strings.Left(response, Strings.Len(tag) + 1) = tag & " " Then 'или с тагом
          CallTrace("Rx '{0}'", response)
          Exit Do
        End If
      Loop
      Return Mid(response, InStr(response, " ") + 1, 2) = "OK"
    End Function

    ''' <summary>
    ''' reconnect, if there is a timeout exception and isAutoReconnect is true
    ''' 
    ''' </summary>
    Private Function executeReconnect(ByVal ex As IOException, ByVal command As String, _
     ByVal commandBytes As Byte(), Optional ByVal tag As String = ".") As Boolean
      If Strings.Len(tag) = 0 Then tag = "."
      If ex.InnerException IsNot Nothing AndAlso TypeOf ex.InnerException Is SocketException Then
        'SocketException
        Dim innerEx As SocketException = DirectCast(ex.InnerException, SocketException)
        If innerEx.ErrorCode = 10053 Then
          'probably timeout: An established connection was aborted by the software in your host machine.
          CallWarning("ExecuteCommand", "", "probably timeout occured")
          If m_isAutoReconnect Then
            'try to reconnect and send one more time
            isTimeoutReconnect = True
            Try
              CallTrace("   try to auto reconnect")
              Connect()

              CallTrace("   reconnect successful, try to resend command")
              CallTrace("Tx '{0}'", tag & " " & command)
              ImapStream.Write(commandBytes, 0, commandBytes.Length)
              ImapStream.Flush()
              Return True
            Finally
              isTimeoutReconnect = False
            End Try

          End If
        End If
      End If
      Return False
    End Function

    ''' <summary>
    ''' read single line response from IMAP server. 
    ''' <example>Example server response: *OK asdfkjahsf</example>
    ''' </summary>
    ''' <param name="response">response from IMAP server</param>
    ''' <returns>true: positive response</returns>
    Protected Function readSingleLine(ByRef response As String) As Boolean
      response = Nothing
      Try
        response = ImapStreamReader.ReadLine()
      Catch ex As Exception
        Dim s As String = ex.Message
      End Try
      If response Is Nothing Then
        Throw New ImapException("Server " + m_ImapServer + " has not responded, timeout has occured.")
      End If
      CallTrace("Rx '{0}'", response)
      Return (response.Length > 0 AndAlso response(0) = "*"c)
    End Function

    ' ''' <summary>
    ' ''' read one line in multiline mode from the IMAP server. 
    ' ''' </summary>
    ' ''' <param name="response">line received</param>
    ' ''' <returns>false: end of message</returns>
    'Protected Function readMultiLine(ByRef response As String) As Boolean
    '  response = Nothing
    '  response = ImapStreamReader.ReadLine()
    '  If response Is Nothing Then
    '    Throw New ImapException("Server " + m_ImapServer + " has not responded, probably timeout has occured.")
    '  End If
    '  If isTraceRawEmail Then
    '    'collect all responses as received
    '    RawEmailSB.Append(response & CRLF)
    '  End If
    '  'check for byte stuffing, i.e. if a line starts with a '.', another '.' is added, unless
    '  'it is the last line
    '  If response.Length > 0 AndAlso response(0) = "."c Then
    '    If Mid(response, InStr(response, " ") + 1, 2) = "OK" Then
    '      CallTrace("Rx '{0}'", response)
    '      'closing line found
    '      Return False
    '    End If
    '    'remove the first '.'
    '    response = response.Substring(1, response.Length - 1)
    '  End If
    '  Return True
    'End Function

  End Class

End Namespace

...
Рейтинг: 0 / 0
15 сообщений из 40, страница 2 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / А про IMAP не разжуете?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]