Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Problema nel leggere hedaer email
Forum - C# / VB.NET - Problema nel leggere hedaer email

Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 16:51
Lunedì, 06/04/2009
Questo topic è stato chiuso dal moderatore

Allora ho creato un programma che si connette alla mia casella gmail e che preleva tutti i messaggi.
Il problema è che io non riesco a estrapolare dal messaggio il mittente e il messaggio vero e proprio.
Penso che lo debba fare tramite espressioni regolari ma non ho la più pallida idea di come fare!


PS: Qualcuno conosce una classe che permetta di connettersi ad un server POP3 sensa sorbirsi tutto il protocollo!
(Io uso TCPClient per inviare volta volta i dati x l'autenticazione e controllare se le risposte sono giuste. Sarebbe bello esistesse una classe che faccia tutto in automatico!)


Ah scusate: Il linguaggio è VB.net

Ultima modifica effettuata da AlesPalla il 06/04/2009 alle 17:01
PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 15:38
Martedì, 07/04/2009
I socket sono l'unico modo. Puoi comunque crearti una classe wrapper molto più comoda, che potrai riusare anche in casi successivi. Io lo faccio sempre.
Espressioni regolari:
http://totem.altervista.org/guida/versione2/C3.php

Mi piacerebbe anche vedere il codice dato che i miei tentativi sono sempre falliti, a causa del fatto che nessuno dei miei indirizzi email supporta il POP3.

PM
Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 21:16
Martedì, 07/04/2009
Premetto subito che il codice è ancora moooolto rozzo:
devo aggiungere controlli x le eccezioni, poi ci sono variabili superflue che potrei eliminare, elementi ripetitivi che potrei trasformare in procedure/funzioni ecc...
Inoltre devo ringraziarti x i codici di ricezione e di invio di dati che li ho presi dalla tua guida e che sono i miglioritra quelli che ho testato.



Codice sorgente - presumibilmente VB.NET

  1. Imports System.Net.Sockets
  2. Imports System.Text.ASCIIEncoding
  3.  
  4.  Public Function Connetti(ByVal username As String, ByVal pass As String)
  5.         'Provo a connettermi
  6.         Dim client As New TcpClient
  7.         Dim NetStr As NetworkStream
  8.         'x vedere se va a buon fine
  9.         Dim S As String = ""
  10.         client.Connect("pop.gmail.it", 110)
  11.  
  12.         netstr = client.GetStream()
  13.  
  14.  
  15.         '\\\\Conferma connessione
  16.  
  17.         Dim A As Boolean = False
  18.         Dim mystring As String = Nothing
  19.         Do
  20.             Dim byteServer(client.ReceiveBufferSize) As Byte
  21.             If Not (client.ReceiveBufferSize = 0) Then
  22.                 netstr.Read(byteServer, 0, byteServer.Length)
  23.                 mystring = ASCII.GetString(byteServer)
  24.  
  25.                 A = True
  26.             End If
  27.         Loop Until A = True
  28.         A = False
  29.  
  30.         '\\\\\Parte 1 (Username)
  31.         If mystring.StartsWith("+OK") Then
  32.             Dim bytes1() As Byte = ASCII.GetBytes("USER " + username + vbCrLf)
  33.             netstr.Write(bytes1, 0, bytes1.Length)
  34.         Else
  35.             Return S
  36.             client.Close()
  37.             MsgBox("Disconnesso")
  38.             Exit Function
  39.         End If
  40.  
  41.  
  42.         '\\\\\\Ricevi conferma username
  43.        
  44.  
  45.         Do
  46.             Dim byteServer(client.ReceiveBufferSize) As Byte
  47.             If Not (client.ReceiveBufferSize = 0) Then
  48.                 netstr.Read(byteServer, 0, byteServer.Length)
  49.                 mystring = ASCII.GetString(byteServer)
  50.  
  51.                 A = True
  52.             End If
  53.         Loop Until A = True
  54.         A = False
  55.  
  56.         '\\\\\\Parte 2(Pass)
  57.         If mystring.StartsWith("+OK") Then
  58.  
  59.             Dim bytes2() As Byte = System.Text.Encoding.ASCII.GetBytes("PASS " + pass + vbCrLf)
  60.  
  61.             netstr.Write(bytes2, 0, bytes2.Length)
  62.         Else
  63.             Return S
  64.             client.Close()
  65.             MsgBox("Disconnesso")
  66.             Exit Function
  67.         End If
  68.  
  69.         '\\\Ricevi conferma pass
  70.  
  71.         Do
  72.             Dim byteServer(client.ReceiveBufferSize) As Byte
  73.             If Not (client.ReceiveBufferSize = 0) Then
  74.                 netstr.Read(byteServer, 0, byteServer.Length)
  75.                 mystring = ASCII.GetString(byteServer)
  76.  
  77.                 A = True
  78.             End If
  79.         Loop Until A = True
  80.         A = False
  81.  
  82.         '\\\Parte 3(Elenco Messaggi)
  83.         If mystring.StartsWith("+OK") Then
  84.  
  85.             Dim bytes3() As Byte = System.Text.Encoding.ASCII.GetBytes("list " + vbCrLf)
  86.  
  87.             netstr.Write(bytes3, 0, bytes3.Length)
  88.         Else
  89.             Return S
  90.             client.Close()
  91.             MsgBox("Disconnesso")
  92.             Exit Function
  93.         End If
  94.         '\\\Ricevi elenco messaggi
  95.         mystring = ""
  96.         Do
  97.             Dim byteServer(client.ReceiveBufferSize) As Byte
  98.             If Not (client.ReceiveBufferSize = 0) Then
  99.                 netstr.Read(byteServer, 0, byteServer.Length)
  100.                 S = ASCII.GetString(byteServer)
  101.  
  102.                 A = True
  103.             End If
  104.         Loop Until A = True
  105.         A = False
  106.         Dim arr() As String
  107.         mystring = S.Replace("+OK POP3 clients that break here, they violate STD53." + vbCrLf, Nothing)
  108.         arr = mystring.Split(vbCrLf)
  109.  
  110.         For Each I In arr
  111.             Dim h As String() = I.Split(" ")
  112.             If h(0).Contains(".") = True Or h(0) = " " Then
  113.                 Exit For
  114.             End If
  115.             Dim x As Char() = h(0).ToCharArray()
  116.             Dim b As String = ""
  117.             For Each T In x
  118.                 If (T = "0" Or T = "1" Or T = "2" Or T = "3" Or T = "4" Or T = "5" Or T = "6" Or T = "7" Or T = "8" Or T = "9") Then
  119.                     b += T
  120.                 End If
  121.             Next
  122.             MsgBox(b)
  123.             Messaggio(b, client, NetStr)
  124.  
  125.  
  126.             'elimina i messaggi
  127.             If b.Contains(" ") = False Then
  128.                 Dim by() As Byte =ASCII.GetBytes("dele " + b + vbCrLf)
  129.                 NetStr.Write(by, 0, by.Length)
  130.             End If
  131.  
  132.             A = False
  133.  
  134.             Do
  135.                 Dim byteServer(client.ReceiveBufferSize) As Byte
  136.                 If Not (client.ReceiveBufferSize = 0) Then
  137.                     NetStr.Read(byteServer, 0, byteServer.Length)
  138.                     mystring = ASCII.GetString(byteServer)
  139.  
  140.                     A = True
  141.                 End If
  142.             Loop Until A = True
  143.  
  144.         Next
  145.        
  146.         A = False
  147.  
  148.  
  149.  
  150.         '\\\Parte finale(Quit)
  151.  
  152.  
  153.         Dim bytes() As Byte = ASCII.GetBytes("quit" + vbCrLf)
  154.  
  155.         NetStr.Write(bytes, 0, bytes.Length)
  156.  
  157.         client.Close()
  158.         MsgBox("Disconnesso")
  159.  
  160.         Return S
  161.     End Function
  162.  
  163.  
  164.  
  165.  
  166. Private Sub Messaggio(ByVal I As String, ByVal client As TcpClient, ByVal netstr As NetworkStream)
  167.         If I.Contains(" ") = True Then
  168.             Exit Sub
  169.         End If
  170.         Dim S As String = ""
  171.         Dim A As Boolean = False
  172.        
  173.         '\\\Parte 4(leggi messaggio)
  174.  
  175.  
  176.         Dim bytes() As Byte = ASCII.GetBytes("retr " + I + vbCrLf)
  177.  
  178.         NetStr.Write(bytes, 0, bytes.Length)
  179.  
  180.  
  181.         Do
  182.             Dim byteServer(client.ReceiveBufferSize) As Byte
  183.             If Not (client.ReceiveBufferSize = 0) Then
  184.                 NetStr.Read(byteServer, 0, byteServer.Length)
  185.                 S = ASCII.GetString(byteServer)
  186.  
  187.                 A = True
  188.             End If
  189.         Loop Until A = True
  190.         A = False
  191.  
  192.         Do
  193.             Dim byteServer(client.ReceiveBufferSize) As Byte
  194.             If Not (client.ReceiveBufferSize = 0) Then
  195.                 NetStr.Read(byteServer, 0, byteServer.Length)
  196.                 S = ASCII.GetString(byteServer)
  197.  
  198.                 A = True
  199.             End If
  200.         Loop Until A = True
  201.         A = False
  202.  
  203.         TextBox1.Text = S
  204.  
  205.  
  206.  
  207.  
  208.  
  209.     End Sub




Ps: Io uso i commenti il meno possibile perchè mi distraggono, quindi se qualche parte è poco chiara chiedi pure.

Comunque il mio problema sta nella procedura messaggio visto che non riesco a distinguere nella stringa S il campo from e il messaggio vero e proprio.

Ultima modifica effettuata da AlesPalla il 07/04/2009 alle 21:22
PM
Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 10:32
Mercoledì, 08/04/2009
Grazie alla guida sono riuscito a isolare il campo from

Codice sorgente - presumibilmente VB.NET

  1. Dim Email As New Regex("(From: )\b(\w+)\s*(@|at|\[at\])\s*(\w+)\s*(\.|dot|\[dot\])(\w+)", RegexOptions.Multiline)
  2.         For Each M As Match In Email.Matches(S)
  3.             From = M.Groups(2).Value + "@" + M.Groups(4).Value + "." + M.Groups(6).Value
  4.  
  5.         Next



Ma per il corpo del messaggio non c'è verso...

PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 16:00
Mercoledì, 08/04/2009
Beh io non so come viene formattata la risposta. Se mi mandi un esempio posso aiutarti.

PM
Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 9:33
Giovedì, 09/04/2009
Codice sorgente - presumibilmente Delphi

  1. Return-Path: <mittente>
  2. X-Original-To: destinatario
  3. Delivered-To: destinatario
  4. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  5.         by gmail.it (Postfix) with ESMTP id 26878134C8C9
  6.         for <destinatario>; Tue,  7 Apr 2009 23:46:49 +0200 (CEST)
  7. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  8.         by gmail.it (Postfix) with ESMTP id F1464134C8C8
  9.         for <destinatario>; Tue,  7 Apr 2009 23:46:48 +0200 (CEST)
  10. X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on
  11.         km33637.keymachine.de
  12. X-Spam-Level:
  13. X-Spam-Status: No, score=0.0 required=7.0 tests=none autolearn=disabled
  14.         version=3.2.5
  15. Received: from cp-out7.libero.it (cp-out7.libero.it [212.52.84.107])
  16.         by gmail.it (Postfix) with ESMTP
  17.         for <destinatario>; Tue,  7 Apr 2009 23:46:48 +0200 (CEST)
  18. Received: from alessand-1095b8 (151.49.12.238) by cp-out7.libero.it (8.5.016.1)
  19.         id 49C8EC350149E408 for destinatario; Tue, 7 Apr 2009 23:45:28 +0200
  20. Message-ID: <49C8EC350149E408@cp-out7.libero.it> (added by postmaster@cp-out7.libero.it)
  21. MIME-Version: 1.0
  22. From: mittente
  23. To: destinatario
  24. Date: 7 Apr 2009 23:45:24 +0200
  25. Subject: prova
  26. Content-Type: text/plain; charset=iso-8859-1
  27. Content-Transfer-Encoding: quoted-printable
  28. X-Virus-Scanned: ClamAV using ClamSMTP
  29.  
  30.  
  31. Qui c'è il testo
  32.  
  33. .


Mittente=indirizzo di partenza
Destinatario= indirizzo finale

Ultima modifica effettuata da AlesPalla il 09/04/2009 alle 9:35
PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 9:40
Giovedì, 09/04/2009
In effetti è un bel problema. Ci dovrebbe essere anche il campo Contet-Length alla fine, perchè qui non c'è?

PM
Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 14:52
Sabato, 11/04/2009
Allora no il campo Content-Lenght non c'è ma ho parzialmente aggirato il problema.
Mi sono letto tutta la documebntazione sul pop3 e ho trovato il comado top.
Questo necessita di 2 parametri, il numero del messaggio e il numero di righe del corpo del messaggio da visualizzare.
Quindi se io voglio leggere gli header di un messaggio(x esempio il numero 1) faccio top 1 0 e ottengo gli header del messaggio, e fin qui nessun problema...
Per esempio di questo messaggio:

Codice sorgente - presumibilmente Delphi

  1. Return-Path: <mittente>
  2. X-Original-To: deestinatario
  3. Delivered-To: destinatario
  4. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  5.         by gmail.it (Postfix) with ESMTP id 294602A0200C
  6.         for <destinatario>; Wed,  8 Apr 2009 10:52:19 +0200 (CEST)
  7. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  8.         by gmail.it (Postfix) with ESMTP id 00D7B2A02002
  9.         for <destinatario>; Wed,  8 Apr 2009 10:52:19 +0200 (CEST)
  10. X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on
  11.         km33637.keymachine.de
  12. X-Spam-Level:
  13. X-Spam-Status: No, score=0.0 required=7.0 tests=none autolearn=disabled
  14.         version=3.2.5
  15. Received: from cp-out9.libero.it (cp-out9.libero.it [212.52.84.109])
  16.         by gmail.it (Postfix) with ESMTP
  17.         for <destinatario>; Wed,  8 Apr 2009 10:52:18 +0200 (CEST)
  18. Received: from alessand-1095b8 (151.49.49.125) by cp-out9.libero.it (8.5.016.1)
  19.         id 49C8ECEA0152A325 for recivitor@gmail.it; Wed, 8 Apr 2009 10:41:48 +0200
  20. Message-ID: <49C8ECEA0152A325@cp-out9.libero.it> (added by postmaster@cp-out9.libero.it)
  21. MIME-Version: 1.0
  22. From: mittente
  23. To: destinatario
  24. Date: 8 Apr 2009 10:41:44 +0200
  25. Subject: ciao
  26. Content-Type: text/plain; charset=iso-8859-1
  27. Content-Transfer-Encoding: quoted-printable
  28. X-Virus-Scanned: ClamAV using ClamSMTP
  29.  
  30. prova 2
  31. .



ottengo (dopo alcune formattazioni) questo header:

Codice sorgente - presumibilmente Delphi

  1. Return-Path: <mittente>
  2. X-Original-To: destinatario
  3. Delivered-To: destinatario
  4. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  5.         by gmail.it (Postfix) with ESMTP id 294602A0200C
  6.         for <destinatario>; Wed,  8 Apr 2009 10:52:19 +0200 (CEST)
  7. Received: from gmail.it (localhost.localdomain [127.0.0.1])
  8.         by gmail.it (Postfix) with ESMTP id 00D7B2A02002
  9.         for <destinatario>; Wed,  8 Apr 2009 10:52:19 +0200 (CEST)
  10. X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on
  11.         km33637.keymachine.de
  12. X-Spam-Level:
  13. X-Spam-Status: No, score=0.0 required=7.0 tests=none autolearn=disabled
  14.         version=3.2.5
  15. Received: from cp-out9.libero.it (cp-out9.libero.it [212.52.84.109])
  16.         by gmail.it (Postfix) with ESMTP
  17.         for <destinatario>; Wed,  8 Apr 2009 10:52:18 +0200 (CEST)
  18. Received: from alessand-1095b8 (151.49.49.125) by cp-out9.libero.it (8.5.016.1)
  19.         id 49C8ECEA0152A325 for recivitor@gmail.it; Wed, 8 Apr 2009 10:41:48 +0200
  20. Message-ID: <49C8ECEA0152A325@cp-out9.libero.it> (added by postmaster@cp-out9.libero.it)
  21. MIME-Version: 1.0
  22. From: mittente
  23. To: destinatario
  24. Date: 8 Apr 2009 10:41:44 +0200
  25. Subject: ciao
  26. Content-Type: text/plain; charset=iso-8859-1
  27. Content-Transfer-Encoding: quoted-printable
  28. X-Virus-Scanned: ClamAV using ClamSMTP



supponiamo che il messaggio sia una variabile string S e gli header siano una variabile string h.
Quindi per avere il corpo del messaggio io faccio:
S=S.replace(h,nothing)
ma mi da sempre la stringa originale!!!

ho provato pure a comparare tramite hash md5 la tringa header e la sua corrispettiva nel messaggio e danno lo stesso hash!


Ho come la sensazione di perdermi in un bicchier d'acqua...

PM
Avatar
AlesPalla (Normal User)
Rookie


Messaggi: 25
Iscritto: 23/11/2008

Segnala al moderatore
Postato alle 15:27
Sabato, 11/04/2009
ok ho risolto con un metodo altamente rozzo....

Codice sorgente - presumibilmente VB.NET

  1. Private Function body(ByVal headers As String, ByVal msg As String, ByVal client As TcpClient, ByVal netstr As NetworkStream)
  2.         Dim A() As Char
  3.         A = headers.ToCharArray
  4.         Dim B() As Char
  5.         B = msg.ToCharArray
  6.         Dim C(msg.Length - headers.Length) As Char
  7.         Dim m As Int16 = 0
  8.         For n = 0 To A.Length - 1
  9.             If Not (A(n) = B(n)) Then
  10.                 C(m) = B(n)
  11.                 m = m + 1
  12.             End If
  13.  
  14.         Next
  15.         Dim S As String = ""
  16.         For Each h In C
  17.             S += h
  18.         Next
  19.         Return S
  20.     End Function


Comunque funziona...


Grazie mille per la disponibilità

PM