[VB6] Problemen met uitlezen POP3 emailbox

Pagina: 1
Acties:

  • TweakersOnly
  • Registratie: September 2000
  • Laatst online: 23:14
Ik heb in VB6 een programmaatje gemaakt dat met behulp van Winsock inlogt op mailserver met username en password en alle emailberichten op de server ophaalt.

Allereerst haal ik met commando "STAT" het aantal emailberichten op. Daarna haal ik door middel van een loop alle emailberichten op en laat het onderwerp zien.

De onderstaande code is globaal, heb de exacte code niet bij de hand:

Visual Basic 6:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dim intHuidigemailbericht as integer
dim intTotaalaantalberichten as integer


private sub page_load()
   intTotaalaantalberichten = 20
   intHuidigemailbericht = 1
end sub


private sub winsock1_dataArrival (ByVal BytesTotal as Long)
   string strServerantwoord as string
   Winsock1.Getdata strServerantwoord, vbString, BytesTotal
   if (intHuidigemailbericht <= intTotaalaantalberichten)
      Winsock1.Senddata "RETR " & intHuidigemailbericht & vbCrLf
      intHuidigemailbericht = intHuidigemailbericht + 1
   end if
end sub


Door middel van de sub winsock1_dataArrival worden alle emailberichten opgehaald. Echter de daaropvolgende Winsock1.GetData vult de string strServerantwoord niet altijd in.

De functie op zich werkt wel goed. Het probleem treedt onregelmatig op. Soms gebeurt dit bijvoorbeeld bij bericht 2, 3 en 6, een andere keer bij bericht 5 en 7.

Ik vermoed dat de dataArrival-procedure niet genoeg tijd krijgt om alle gegevens binnen te halen. Heeft iemand een vermoeden wat er verkeerd gaat?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Je haalt meteen een volgend bericht op (RETR) terwijl je niet eens ween of het huidige bericht helemaal binnen is... :?

En
code:
1
string strServerantwoord as string


moet zijn
code:
1
Dim strServerantwoord as string


denk ik ;)

Tot slot gebruik je gewoon een teller voor je RETR, maar als ik me niet vergis mag je er niet van uit gaan dat de nummers netjes sequentieel oplopen. Maar daar ben ik niet zeker van, dan zou je de rfc's erop na moeten slaan.

[ Voor 75% gewijzigd door RobIII op 03-03-2004 22:44 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • TweakersOnly
  • Registratie: September 2000
  • Laatst online: 23:14
Je haalt meteen een volgend bericht op (RETR) terwijl je niet eens ween of het huidige bericht helemaal binnen is... :?
Dat vermoeden had ik ook al. De code geeft te snel een nieuw commando aan de winsock. Heb echter nergens iets kunnen vinden om te controleren of alle data binnen is
En
code:
1
string strServerantwoord as string


moet zijn
code:
1
Dim strServerantwoord as string


denk ik ;)
Inderdaad, code is ff uit de losse pols getypt. :)
Tot slot gebruik je gewoon een teller voor je RETR, maar als ik me niet vergis mag je er niet van uit gaan dat de nummers netjes sequentieel oplopen. Maar daar ben ik niet zeker van, dan zou je de rfc's erop na moeten slaan.
Alle emailberichten zijn sequentieel genummerd, behalve als je via telnet/winsock het DELE commando geeft. :)

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
TweakersOnly schreef op 03 maart 2004 @ 22:43:
[...]
Dat vermoeden had ik ook al. De code geeft te snel een nieuw commando aan de winsock. Heb echter nergens iets kunnen vinden om te controleren of alle data binnen is
Da's voor mij lang geleden :Y) Ik zou het niet meer zo 1 2 3 weten. Was het niet zo dat een message altijd eindigt met een regel met aléén een punt?

Verder begrijp je het niet helemaal denk ik: Het DataArrival event wordt wel getriggered, maar je hebt nooit de garantie dat je ALLE data ontvangt. Het kan ook maar een deel van het, in dit geval email-bericht, zijn. Je moet dus wachten met de volgende senddata totdat je alle data binnen hebt (ergo: je ontvangen data blijven appenden aan een "temp"-string en checken op een . (+ CrLf??) als laatste teken(s). Dan is je bericht pas binnen)
TweakersOnly schreef op 03 maart 2004 @ 22:43:
[...]
Inderdaad, code is ff uit de losse pols getypt. :)
Dacht ik al ;)
TweakersOnly schreef op 03 maart 2004 @ 22:43:
[...]
Alle emailberichten zijn sequentieel genummerd, behalve als je via telnet/winsock het DELE commando geeft. :)
Ik had er de RFC's al op nageslagen en had het al ontdekt :Y)
After the POP3 server has opened the maildrop, it assigns a message-
number to each message, and notes the size of each message in octets.
The first message in the maildrop is assigned a message-number of
"1", the second is assigned "2", and so on, so that the n'th message
in a maildrop is assigned a message-number of "n". In POP3 commands
and responses, all message-number's and message sizes are expressed
in base-10 (i.e., decimal).
[edit]
Dus even voor de duidelijkheid:
+OK <*******@*******.nl>, POP3 server ready.
USER rob
+OK rob is known here.
pass *******
+OK Welcome! 1 messages (707 bytes)
list
+OK 1 messages, 707 bytes
1 707
.
retr 1
+OK Here it comes...
Received: from spooler by *******.nl (Mercury/32 v4.01a); 3 Mar 2004 22:55:41
+0100
X-Envelope-To: <rob@*******.nl>
Return-path: <rob@*******.nl>
Received: from pcrob (10.10.5.11) by ******* mailserver (Mercury/32 v4.01a) wi
th ESMTP ID MG0003E7;
3 Mar 2004 22:55:32 +0100
From: "Rob" <rob@*******.nl>
To: <rob@*******.nl>
Subject: Test
Date: Wed, 3 Mar 2004 22:55:31 +0100
MIME-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit

Dit is een test bericht. Bla bla bla.

.
Zie je die laatste punt (laatste regel uit quote)? Dat is de indicatie van het einde van het bericht.

Dan krijg je dus zoiets:
code:
1
2
3
4
5
6
7
8
9
Dim strServerantwoord as string

private sub winsock1_dataArrival (ByVal BytesTotal as Long)
   Dim strTMP as string

   Winsock1.Getdata strTMP, vbString, BytesTotal
   strServerAntwoord = strServerAntwoord & strTMP 
   If Right(strTMP,3) = "." & vbCrLf then MsgBox "Klaar!"
end sub

Het kan zijn dat je alleen moet checken op een vbCr of vbLF in plaats van een vbCrLf maar dat vind je vast zelf wel effe uit ;)

[ Voor 86% gewijzigd door RobIII op 03-03-2004 23:15 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • TweakersOnly
  • Registratie: September 2000
  • Laatst online: 23:14
Even een update ...

Ik heb nog wat rondgezocht op internet, maar ik ben niet veel wijzer geworden. Op http://www.aspsimply.com/VB/SMPOP3.aspx staat de applicatie die ik wil hebbem. Aan de hand van username/password wordt via winsock/telnet een connectie gemaakt. Vervolgens wordt elk emailbericht op de server opgehaald met commando RETR.

In deze applicatie worden de attachments gesplitst van het emailbericht, iets wat ik met de standaard telnet-commando's niet voor mekaar krijg. Ik heb de RFC's hiervoor nageslagen, maar kan geen oplossing voor mijn probleem vinden.

Mijn vraag is dus hoe ik de attachments van een emailbericht kan splitsen zodat ik alleen maar de inhoud en de header van een emailbericht kan zien.

  • martijn_brinkers
  • Registratie: November 2001
  • Laatst online: 31-10-2025
Mijn vraag is dus hoe ik de attachments van een emailbericht kan splitsen zodat ik alleen maar de inhoud en de header van een emailbericht kan zien.
Je zal dan een mime parser moeten gebruiken (maken) die het mime bericht opsplitst. Zie oa. RFC 2045 voor MIME (leest niet lekker weg btw ;-)

  • TweakersOnly
  • Registratie: September 2000
  • Laatst online: 23:14
Ik ben erachter gekomen waar het probleem zit. Via TCP wordt een connectie gelegd naar de mailserver. Met het TCP-protocol kunnen echter maximaal 4096 bytes in één keer worden gelezen.

Stel: Bericht 1 heeft een grootte van 4200 bytes.

Als ik RETR 1 als commando geef, dan krijg ik bij de DataArrival functie alleen byte 1 tot en met 4096 terug. Als ik vervolgens RETR 2 als commando stuur, dan komen bij de volgende DataArrival de resterende 104 bytes van bericht 1 terug.

De winsock heeft ook een functie _Complete(), maar deze functie geeft niet het resultaat dat ik wil.

Hoe kan ervoor zorgen dat ik alle bytes van een emailbericht binnen krijg?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Welke code heb je nu dan? Heb je mijn posts héél goed gelezen? Je moet echt wel meer dan 4k kunnen ontvangen, echter dan wordt je DataArrival event wel meerdere keren ge-fired en ik denk dat je daar de mist in gaat.

En @Sjaakie hieronder: Heb jij mijn posts al eens héél goed gelezen? Je zegt precies hetzelfde, maar dan minder compleet ;)

[ Voor 23% gewijzigd door RobIII op 15-03-2004 15:33 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 26-05 01:17
Blijven lezen tot de punt en dan pas een nieuw commando sturen.
Pagina: 1