Problema al recibir datos de un servidor pop3

Tus preguntas. Algoritmos o Grupos de Comandos formando Programas Escripts.
Responder
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Problema al recibir datos de un servidor pop3

Mensaje por Jonny »

Hola

Estoy intentando completar una pequeña librería que inicié hace ya algún tiempo ...

Se trata de funciones para gestionar el correo electrónico mediante sockets.

Hace tiempo desarrollé una función que conseguía enviar e-mails mediante sockets. Ahora que he tenido tiempo y he aprendido el protocolo pop3 estoy desarrollando funciones para gestionar el correo (Conectar al servidor, autentificarse, consultar si hay correos etc).

El problema que tengo, es a la hora de descargar un correo.
Intento descargar un correo electrónico con datos adjuntos pero por algún motivo que desconozco el servidor envía el mensaje como en partes...
Es decir, primero envía las cabeceras, y algún segundo después envía el mensaje, que también llega como por bloques...
No se si esto será normal o se deberá a un problema del servidor (lag o algo de eso). Esto lo he observado con un cliente telnet, haciendo pruebas del protocolo. Al aplicarlo a autoit veo que no puedo recibir el mensaje completo, pues tengo este código:

Func Get_Mail()
Local $LoopTimer=0, $ListMailRecv, $NumMails=1
For $I=1 To $NumMails Step +1
TcpSend($ClientSocket[0], "retr "&$I&@CRLF)
While 1
Sleep(1)
$Data=TcpRecv($ClientSocket[0], 2048)
If ($Data<>"" Or $LoopTimer>=5000) Then ExitLoop
$ListMailRecv&=$Data
$LoopTimer+=1
Wend
$LoopTimer=0
msgbox(0, "", $ListMailRecv)
Next
EndFunc

que lo que haría es descargar mediante un bucle todos los mensajes que hubieran en el servidor (las funciones para conectar y consultar el correo no las pongo porque creo qe no son relevantes para el problema)
Como veis, en el while que recibe los datos del servidor puse una especie de temporizador para precisamente que no saliera si no se recibía nada, hasta pasados 5 segundos, por lo que comentaba antes de que el servidor envía la información por bloques.
Pero no se el porqué, no funciona. Unicamente recibo la primera línea y luego se termina el bucle... (algo un poco extraño ¿Verdad?

Haber si alguien tiene idea de como solucionarlo y conseguir que salga del bucle únicamente cuando se termina de recibir datos...
Lo intenté con @Error, pero devuelve 0 tanto si recibe información, como si no recibe nada (en una de esas pausas que hace el servidor) como si se ha terminado de recibir toda la información (el servidor no desconecta al cliente cuando termina de enviar los datos) así, que no vale comprobar si vale -1...

Gracias de antemano.

Salu2!
Pablo2m
Hacker del Foro
Mensajes: 88
Registrado: 28 May 2008, 21:16
Ubicación: Agentina

Re: Problema al recibir datos de un servidor pop3

Mensaje por Pablo2m »

Hola estaba tratando de entender el codigo (nunca he hecho algo que tenga que ver con redes) y vi el sleep cada 1 milisegundo que has puesto para luego sumar $LoopTimer,me parece bastante engorroso mirar cada 1 milisegundo que pasa pero no tengo idea si se puede hacer disitinto, lo que es casi seguro es que tardara mas de 5 segundos en dejar de tratar de recibir algun fragmento paquete . Habria que medir con TimerInit () y TimerDiff() que se tarda en ejecutar los 5000 TcpRecv y demas. Ahora bien con respcto al codigo no tengo idea que pasa
Saludos
Pablo
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Problema al recibir datos de un servidor pop3

Mensaje por Jonny »

Hola

Muchas gracias por tu respuesta.

La verdad, es que tocar código que tenga que ver con redes, es bastante complicado (si quiere hacerse bien) al menos para mí, que estoy empezando ahora también.

Sí, el código que puse veo que no es el más idóneo y parece que tienes razón...

Buscando mientras alguien me daba una respuesta encontré la librería que adjunto en este mensaje, que contiene barias funciones interesantes para el protocolo pop3, sin enbargo le encuentro una pega, y es que la función _pop3connect() no da la posibilidad de encriptar la contraseña a la hora de enviarla al servidor y autentificarse así mediante apop en vez de con los comandos basicos "user" y "pass", en los que los datos no se encriptan...
Eso quizá, podría solucionarse fácilmente, de hecho yo tengo una función para conectar al servidor, comprobar si admite la autntificación con apop y autentificarse encriptando la contraseña (siguiendo el protocolo pop3) o de la forma tradicional...
Pero la verdad es que no me terminó de apetecer y opté por utilizar las funciones que estaba desarrollando para mi proyecto salvo las que incluye esta librería para recibir e-mails, que parecen funcionar y muy bien.

Aquí teneis la librería que descargué del foro inglés de autoit, por si a alguien le interesa y no le gusta complicarse la vida como amí...

Que la disfruteis!

Salu2!
Adjuntos
_pop3.rar
(3.17 KiB) Descargado 195 veces
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Problema al recibir datos de un servidor pop3

Mensaje por Jonny »

Hola

Cuando escribí recientemente el post anterior, parecía estar todo solucionado...

Pero haciendo pruebas con mi dirección de correo y poniendo a prueba la función que he montado para descargar los e-mails con uno que contenga archivos adjuntos ... ha llegado el problema de nuevo.
La aplicación se cuelga y no hay forma de que tire, salvo matar el proceso desde el administrador de tareas...

Decir, que no es un archivo adjunto muy grande, se trata de un pps...
¿Porqué no funcionará cuando se trata de mucha información?
¿Será que la función TCPRecv() no soporta grandes cantidades de datos?...
En la ayuda del manual original de autoit no he visto nada sobre esto....
Por cierto, la cuestión es que yo lo que necesito es comprobar si el e-mail contiene archivo/s adjunto/s, y si es así no descargarlo...
Pero la única forma que se me ocurre por el momento de comprobarlo es descargando el e-mail y comprobar la cabecera que lo indica, ya que con top # all
no aparece dicha cabecera.
¿Alguien sabe como puedo comprobar si el e-mail contiene datos adjuntos sin necesidad de descargar todo el e-mail?

Si fuera posible tendría el problema resuelto, pues con e-mails de texto aparentemente funciona bien...

Salu2!
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Problema al recibir datos de un servidor pop3

Mensaje por Chefito »

No....si al final gracias a tí voy a convertirme en un experto en las funciones de comunicación :smt005 .
He estado mirando el código. Lo que tienes que hacer para no bajar el archivo, es tratar el texto del mensaje que se va bajando poco a poco.
Me he fijado que tiene varias cosas que las cuales se pueden utilizar para cortar la bajada del mensaje antes de que se baje el archivo.
El encabezado del texto plano es:
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
El encabezado del código html es:
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
El encabezado del archivo es:
Content-Type: video/avi
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="BOTON.avi"
También se observa dos códigos únicos....por ejemplo en uno de los mensaje (el 2º), los cuales son
--_1b62d767-37d2-496b-bc2a-2226323f3404_
y
_51f5a604-eca1-4f68-84a2-965d3147b97d_
.
Mira cuales puedes utilizar mejor para cortar el mensaje. Por ejemplo, la linea undary="_1b62d767-37d2-496b-bc2a-2226323f3404_" es la 1º que aparece......con esto sería muy facil sacar este código.

Por cierto.....todo lo que tengas que hacer para cortar la transferencia del correo, se tiene que meter en el bucle while de la función _Pop3Retr. Vamos, que tienes que encontrar alguna combinación de strings, y si se cumple la condición salir del bucle :smt003 .

A ver que se te ocurre :smt024 .
Si tienes problemas dimelo y lo sacamos.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Problema al recibir datos de un servidor pop3

Mensaje por Jonny »

Hola

tendría que mirar las cabeceras que dices ... creo que de ellas, la única con la que se podría trabajar fácilmente sabiendo que es cien por cien fiable es la que indica que hay archivo adjunto (attachment) ¿no?...
las demás, también podrían utilizarse, pero por ejemplo la que indica que es video/audio podría tener otros valores ¿no? según si el adjunto es zip, rar, exe.... (imagino que esto cambiará el contenido de esa cabecera)
¿el mensaje se descarga poco a poco?...
la verdad es que con este código no me he parado mucho a entenderlo, pues utiliza bucles con temporizadores etc, que añadido a un timer a modo de hilo ... :P.
El problema de las cabeceras que podrían analizarse para determinar si hay datos adjuntos en el correo, es que aparecen después del cuerpo del mensaje, así que practicamente hay que descargarlo todo...
Sinó, con el comando top tel protocolo pop3 sería muy sencillo.

Se me está ocurriendo ahora, que otra forma podría ser comprobar si lo que se recibe es string o binary ¿que te parece?... Creo que hay funciones para ambas comprobaciones ¿Verdad? (nunca he tocado cadenas de datos binarios) pero creo recordar algo como "IsBinary()".
Si se reciben datos binarios dejo de descargar el mensaje...

Salu2!
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Problema al recibir datos de un servidor pop3

Mensaje por Chefito »

ESTE MENSAJE QUEDA EN ESPERA DE PONER EL LINK DEL CÓDIGO POR PROBLEMAS DE ÚLTIMA HORA EN EL CÓDIGO <<<<<<< SOLUCIONADO!!!
Bueno....lo prometido es deuda. ACABE!!!! Jejejeje....me ha costado un poquito pero creo que lo locré (por lo menos funciona bien con los mails que tu y yo hemos enviado......no se si con otros servidores de correo valdría igual. Espero que sí...puffff).
He añadido unas funciones nuevas. En definitiva una para descargarte solamente la información del mensaje (quien lo ha enviado, a quien, asunto del mensaje y fecha de envio).
Otra para descargarte solamente el cuerpo del mensaje. Le he añadido algunas opciones :smt033 . Puedes descargarte la parte del cuerpo del mensaje en texto plano o en html. También le he tenido que añadir una especie de codificador, ya que algunos mensajes salían sin acentuar y demás. No se si se codificaran con algún protocolo :smt017 . Esa parte es la única que no he investigado.
Y la última función....pufffff.....te baja los archivos adjuntos y te los almacena en el disco duro!!!! :smt002 . Una maravilla jajaja.
Voy a colgar las funciones y los archivos en el subforo eScript, http://www.emesn.com/autoitforum/viewto ... f=4&t=1502 <<<<<EDITADO

Ahora te intentaré responder a tus preguntas:
Jonny escribió:tendría que mirar las cabeceras que dices ... creo que de ellas, la única con la que se podría trabajar fácilmente sabiendo que es cien por cien fiable es la que indica que hay archivo adjunto (attachment) ¿no?...
Una de las partes las he tratado con esta palabra. Pero siempre tienes que tener en cuenta los código únicos que te salen en el mensaje para tratar otras partes, ya que tratar texto puede ser un arma de doble filo, y el mensaje podría llevar ese texto que quieres tratar y confundirías al programa. Por eso tienes que tener en cuenta los códigos que te genera el mail, ya que eso es casi imposible que aparezcan.
Jonny escribió:¿el mensaje se descarga poco a poco?...
El mensaje se descarga a la velocidad que tu le digas :smt001 . El tamaño de descarga está en esta linea de código de la función _WaitTcpResponse.

Código: Seleccionar todo

$ret = TCPRecv ($pop3_socket, 128)
Esto indica que el máximo de caracteres que recibirá de cada vez sera de 128.
Jonny escribió:la verdad es que con este código no me he parado mucho a entenderlo, pues utiliza bucles con temporizadores etc, que añadido a un timer a modo de hilo ... :P.
Este código de temporizadores tiene poco :smt016 . Alguna función tiene condiciones de tiempo para mandar un error por si no responde el servidor....pero poco más.
Si se podría hacer con timers de forma asíncrona??? Sí, pero ya habría que calentarse otra vez el coco :smt004 . Eso se haría llamando a las funciones con _Timer_SetTimer y poniendo el código dentro de la función una condición diciendo que si no a acabado de ejecutarse todo el código, que el timer no ejecute otra vez la función, para evitar el solapamiento.
También se tendrían que cambiar los whiles por condiciones (If). Supongo que con esto funcionaría. SUPONGO...... :smt017
Jonny escribió:El problema de las cabeceras que podrían analizarse para determinar si hay datos adjuntos en el correo, es que aparecen después del cuerpo del mensaje, así que practicamente hay que descargarlo todo...
Como ya te demuestro en las funciones que he hecho, se puede descargar solamente la información del mensaje por un lado, y por otro el cuerpo del mensaje, y cuando ya lo ha descargado, corta la descarga de los archivos adjuntos....si los hay.
Se podría hacer muy facilmente otra función que te indicase si hay archivos adjuntos o no sin descargarlos. La función que he realizado para descargar los archivos adjuntos devuelve -1 y un error si no los hay. Habría que hacer una mucho más corta a partir de ésta (muy facil :smt003 ). Sería comparando un par de códigos únicos del mail y ya está. <<<<< HE HECHO TAMBIÉN ESTA FUNCIÓN. MIRALA EN EL CÓDIGO.
Jonny escribió:Se me está ocurriendo ahora, que otra forma podría ser comprobar si lo que se recibe es string o binary ¿que te parece?... Creo que hay funciones para ambas comprobaciones ¿Verdad? (nunca he tocado cadenas de datos binarios) pero creo recordar algo como "IsBinary()".
Mmmmm.....no puedes compararlo porque te envía todo en modo caracter. Además, los ficheros estas codificados en base 64. Mira la función y estudiala. Te la he comentado un poco.
Coma ya te he dicho más arriba, es comparando un string con los códigos únicos, y si los encuentra, cortar la descarga.
Jonny escribió:Si se reciben datos binarios dejo de descargar el mensaje...
Eso está solucionado. Una de las funciones solamente descarga el mensaje de texto y corta :smt003 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Problema al recibir datos de un servidor pop3

Mensaje por Chefito »

He editado el mensaje anterior. Ya está más o menos todo solucionado.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Jonny
Profesional del Autoit
Mensajes: 1042
Registrado: 30 Jun 2008, 20:08

Re: Problema al recibir datos de un servidor pop3

Mensaje por Jonny »

uau !

Buen trabajo!

estudiaré bien las funciones que implementaste, en cuanto que tenga un poco de tiempo!
Thanks!
Salu2!
Pablo2m
Hacker del Foro
Mensajes: 88
Registrado: 28 May 2008, 21:16
Ubicación: Agentina

Re: Problema al recibir datos de un servidor pop3

Mensaje por Pablo2m »

Impresionante :smt041
Te felicito Chefito
Saludos
Pablo
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Problema al recibir datos de un servidor pop3

Mensaje por Chefito »

Gracias Pablo :smt002 .
La verdad es que me ha gustado el tema.....aunque me han resultado un poco dificil al principio de implementar.
Al final parece que ha salido algo decente :smt005 .

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Responder