Cómo comprobar el origen de eDonkey
EMule es un programa típico de MFC y su interfaz gráfica se ha integrado estrechamente con MFC. Por lo general, solo se puede ejecutar en la plataforma Windows. Algunos otros proyectos como aMule lo han portado, por lo que tiene una funcionalidad multiplataforma más sólida.
De hecho, existe otro proyecto llamado xMule, pero ya no es popular. En la página de inicio de aMule, puede ver parte de la historia de la migración de eMule a la plataforma Linux. El primer proyecto se llamó lMule, que utilizaba wxwidgets para realizar un trasplante multiplataforma de eMule. Este proyecto no se actualizó en 2003 y luego se transformó en el proyecto xMule, que una vez se convirtió en el reemplazo de facto de eMule en la plataforma Linux. Sin embargo, debido a diferentes filosofías, sus programadores chocaron, lo que llevó a la separación de Amule. Más tarde, el conflicto se volvió grave y en una ocasión pasó de ser una cuestión conceptual a un ataque personal a la otra parte y en una ocasión lanzó un DDos en el sitio web de la otra parte. Posteriormente aMule y xMule fueron dos proyectos completamente diferentes. Actualmente, solo HopeSeekr mantiene xMule y básicamente no hay actualizaciones. Esto es más que impresionante. Durante estas vacaciones de invierno, tuve algunos intercambios con HopeSeekr y sentí que tenía mucha confianza. A menudo me muestra código de aMule y me dice que si miras su código, si lo escribes así, es solo un párrafo de xx. Este tipo de código definitivamente fallará en determinadas circunstancias. Por el contrario, si observa nuestro código xMule, no existe tal problema.
EMule comienza a soportar la tecnología Kad desde la versión 0.42, lo cual es un hito muy importante. Kad es un protocolo DHT que permite a los nodos retener cierta información de contacto de otros nodos y utilizar dicha "red de relaciones" para encontrar cualquier nodo y recurso en toda la red sin ningún servidor central. Por lo tanto, es inútil tratar con la red Kad de eMule como si usara Napster para eliminar directamente el servidor central y atravesar la red Napster. La versión 0.42 fue lanzada el 27 de febrero de 2004, casi un año después de la intranet de eDonkey2000, pero la escala de su red Kad se está expandiendo rápidamente. Tanto Kad en la intranet como eMule usan la estructura Kademlia, pero los formatos de mensajes específicos son diferentes, por lo que las dos redes DHT son incompatibles. Hasta ahora, el número de usuarios de la intranet se mantiene en torno a los 100.000, como se escribe en un artículo reciente. Sin embargo, actualmente no existe una declaración precisa sobre la escala de la red Kad de eDonkey. También podemos ver el poder del software de código abierto. Actualmente, la red Kad de aMule es compatible con la red Kad de eMule y xMule no tiene soporte para Kad. El texto original del protocolo Kad se puede descargar desde la máquina de nuestro laboratorio:
:8080/paper/new/by 20 Conference/IPTPS/IPTPS 02/Kademlia 20A 20 peer 20 information 20 system 20 based en 20 en 20 luego 20 o 20 métrica 28 IPTPS 02 29 pdf
La estructura del código de EMule es muy razonable. Aunque la cantidad de código es relativamente grande, la división entre módulos funcionales sigue siendo relativamente razonable. Esto se puede ver en su documentación de ingeniería. EMule separa los archivos de código que representan funcionalidades de los archivos de código que representan interfaces. Los archivos fuente y los archivos de encabezado son los archivos fuente y los archivos de encabezado del código que implementa la función, mientras que los archivos fuente de la interfaz y los archivos de encabezado de la interfaz son los archivos fuente y los archivos de encabezado que implementan la interfaz gráfica. Dado que el código de eMule es demasiado grande, esta serie omitirá la implementación de la interfaz gráfica y se centrará en analizar el código de la parte de implementación de funciones de eMule. También se seleccionan las partes principales de la implementación de funciones.
Esta sección comenzará con el análisis de eMule.cpp, presentará varias clases funcionales principales utilizadas en eMule y describirá aproximadamente sus funciones. Finalmente, presentamos cómo compilar eMule en VS2003. Hay muchos módulos en emule que son muy útiles. A lo que me refiero es a que es útil en otros programas y podría considerarse su reutilización en otros programas.
Emule.cpp es la implementación de CemuleApp. Por lo tanto, en tiempo de ejecución, InitInstance se ejecutará primero para realizar algún trabajo de inicialización. Desde esta función también podemos ver por primera vez las clases que desempeñarán un papel a lo largo del programa.
El primer paso es calcular algunos directorios comúnmente utilizados por los programas, como archivos de configuración y archivos de registro. El siguiente es ProcessCommandline, que tiene dos funciones. El primero es confirmar el modo de ejecución de eMule, es decir, si hay parámetros después de la línea de comando, y el segundo es confirmar si solo se está ejecutando una instancia de eMule actualmente. Normalmente, no se requieren parámetros al hacer doble clic en un archivo ejecutable de eMule. Pero abrir eMule haciendo clic en un enlace o abriendo un archivo asociado equivale a ejecutar eMule con parámetros. Un programa se puede asociar con un archivo con un enlace o sufijo específico agregando algunas entradas en el registro. Para obtener más información, consulte las funciones de Ask4RegFix, BackupReg y RevertReg en OtherFunctions.cpp en ProcessCommandline. Puede confirmar si se están ejecutando otras instancias de eMule creando un semáforo mutuamente excluyente con un nombre. CreateMutex solo puede crear un mutex para un nombre determinado. Por lo tanto, podemos saber si hay otras instancias de eMule ejecutándose si el semáforo se creó correctamente. Si lo hay, y es un modo con parámetros, puede usar el mecanismo de mensajes de Windows para enviar directamente los parámetros a esa ventana. El siguiente código no es más que cómo encontrar a otro tipo llamado "eDonkey" y qué mensaje enviar. PstrPendingLink es una variable global que representa los parámetros de la línea de comando que se procesarán. Se procesará una vez completada la inicialización.
Las siguientes dos clases más importantes son CPreferences y CStatistics. El primero guarda la mayoría de los datos de configuración del programa y el segundo realiza varias estadísticas. Su característica es que tienen muchas variables miembro y son estáticas, lo que puede garantizar su unicidad y unificar estas variables en una sola clase de gestión. Pero realmente no necesitas saber qué significa cada variable. Prefs y Stats son las únicas instancias de estas dos clases.
Después de hacer algunas otras cosas, incluida la creación de un objeto de interfaz gráfica CemuleDlg, puede ver línea tras línea de declaraciones para crear nuevos objetos. Estas clases implementarán las funciones principales del funcionamiento del programa eMule y se analizarán en detalle en series posteriores.
Finalmente, presentamos cómo compilar eMule en VS2003. Debido a que en eMule se utilizan otras bibliotecas, si el código fuente de eMule se proporciona oficialmente para su descarga, el paquete de código fuente será muy grande. Entonces eMule elige permitir que los desarrolladores vayan a los sitios web oficiales de esas bibliotecas para descargarlas. En términos generales, al compilar dichos archivos de proyecto, es muy importante mantener la coherencia de los parámetros de compilación de cada biblioteca y el programa principal. Entre estos parámetros de compilación, hay tres parámetros principales, a saber, conjunto de caracteres (multibyte/Unicode), depuración/liberación y subproceso único/multiproceso. Hay ocho versiones después de la disposición y combinación. Por lo tanto, si no presta atención al compilar, se producirán errores no relacionados con la programación.
EMule0.47a viene con la biblioteca id3lib después de la descompresión. Debe descargar las siguientes bibliotecas:
zlib:
/~David/cryptlib.html<. /p>
pnglib:
http://www.libpng.org/pub/png/libpng.html
Descárgalos, descomprímelos y compílalos.
Al compilar, preste atención a mantener la coherencia con los parámetros del proyecto de eMule: el conjunto de caracteres es Unicode y admite seguridad de subprocesos múltiples. Puedes elegir la versión de depuración o la versión de lanzamiento según tus necesidades, pero también debe ser coherente con los parámetros de ingeniería de eMule. Los archivos de proyecto VC generalmente se pueden encontrar en los paquetes de descompresión de estas bibliotecas, pero las versiones son inferiores y se pueden convertir directamente. Además, se recomienda que al compilar estas bibliotecas, elija generar bibliotecas estáticas en lugar de bibliotecas dinámicas, para que el archivo ejecutable final generado pueda ejecutarse por sí solo. Después de compilar estas bibliotecas, incluida la biblioteca id3lib y la biblioteca CxImage proporcionada por emule descargada de otros lugares, puede comenzar a compilar eMule. Compilar emule no es más que asegurarse de encontrar todos los archivos de encabezado durante la compilación y todas las bibliotecas durante la vinculación. Al vincular, todas las bibliotecas se pueden encontrar modificando las propiedades en el archivo del proyecto --> Propiedades de configuración -> Vinculador -> Entrada -> Adjuntar las dependencias que se completarán. Pero encontrar todos los archivos de encabezado requiere algunos trucos. Debido a que el código emule contiene los archivos de encabezado de estas bibliotecas, lo que hasta cierto punto define las posiciones relativas de las rutas de esas bibliotecas y las rutas de los proyectos emule, es necesario mover los directorios de las bibliotecas descomprimidas a algunos lugares apropiados. A veces también es necesario cambiar el nombre de estos directorios.
Hay una gran cantidad de archivos de configuración que deben leerse en eMule, y cada archivo de configuración tiene su propio formato definido. Para poder leer y almacenar estos archivos de manera conveniente, eMule tiene una clase de infraestructura muy importante para copiar estas operaciones de archivos, que puede manejar fácilmente la lectura y escritura de algunos tipos de datos comunes y tiene ciertos mecanismos de protección de seguridad. Esta infraestructura se implementa en SafeFile.cpp y SafeFile.h, y hay otra implementación de esta función en el directorio kademlia\io. Las funciones que implementan son básicamente similares, excepto que la versión en el directorio kademlia \ io tiene una función de etiqueta adicional de lectura y escritura. Estas implementaciones están estrechamente relacionadas con otra pieza de infraestructura, que es la conversión de cadenas. StringConversion.cpp y StringConversion.h son la infraestructura en eMule dedicada a replicar varias conversiones de cadenas, como Unicode, secuencias multibyte o UTF-8. Todas las conversiones aquí no son un problema. Con respecto a la conversión de cadenas, personalmente recomiendo usar caracteres anchos Unicode tanto como sea posible, para evitar en la mayor medida los caracteres confusos.
La implementación en el directorio SafeFile.cpp o kademlia\io tiene las características de separar el comportamiento de la operación de datos del objeto de operación de datos. Ambos definen una clase base abstracta para operaciones de datos (CFileDataIO en SafeFile.cpp, Kademlia::CDataIO implementado por DataIO.cpp en el directorio Kademlia). Esta clase solo es responsable de las operaciones lógicas en un dato. Por ejemplo, leer un entero de 32 bits significa leer cuatro bytes en la dirección de un valor entero, similar a leer o escribir otros tipos de datos. Pero esta clase declara todos los métodos físicos de operaciones de datos como funciones virtuales puras, es decir, cuántos bytes se leen y escriben. Con una clase base así, es conveniente sobrecargarla. Al definir estas funciones virtuales puras como operaciones de lectura y escritura en una determinada memoria, se pueden serializar fácilmente datos más complejos en una memoria contigua. Si estas funciones virtuales puras se usan para leer y escribir archivos, naturalmente se pueden usar para leer y escribir archivos de configuración personalizados en varios formatos extraños.
Los objetos de datos leídos por estas clases normalmente incluyen varios tipos de números enteros, cadenas y tokens. Leer y escribir números enteros es relativamente simple. Los métodos para leer y escribir datos de 1 byte, 2 bytes a 4, 8 bytes o 16 bytes son similares. Cabe mencionar aquí que 16 bytes, es decir, 128 bits, es la longitud del ID generado aleatoriamente por la red Kad en eMule, y también es la longitud del resultado generado por el algoritmo hash MD4 comúnmente utilizado en eMule. Estos ID se utilizan a menudo para acceder directamente al archivo completo.
En el directorio kademlia\utils, UInt128.cpp implementa una clase que representa un entero de 128 bits. Esta clase tiene funciones completas y puede realizar algunas operaciones aritméticas y comparaciones. Aparecerá como una clave en la tabla hash. la fundación. Al estudiar detenidamente la implementación del código en UInt128.cpp, puede aprender muchos problemas a los que se debe prestar atención al escribir este tipo de objeto de datos personalizado.
Otra operación muy importante en las operaciones de datos es la cadena. El principio general es escribir primero la extensión y luego el contenido. Sin embargo, durante operaciones específicas, debe prestar atención a estos detalles, como si la longitud es de 4 bytes o 2 bytes y si el contenido de la cadena debe codificarse en UTF-8. Estas operaciones deben coordinarse estrechamente con StringConversion.cpp. De hecho, muchas de las funciones de conversión de cadenas de este último también llaman a funciones relacionadas con ATL, pero están envueltas con una capa de MFC CString.
En CDataIO implementado en kademlia\io\DataIO.cpp, también se implementa la función de lectura y escritura basada en Tag. Es muy importante intercambiar metainformación sobre archivos en Internet. Por lo general, la metainformación de un archivo se puede dividir en muchas etiquetas, como "nombre de archivo = xxx", "longitud de archivo = xxx", etc. En otras palabras, una etiqueta representa el hecho de que un atributo es igual a un determinado valor. Hay muchos códigos definidos en el archivo Opcodes.h, incluidos muchos nombres de atributos de etiquetas comunes. El nombre del atributo de etiqueta almacenado en la clase CDataIO primero almacena un byte, luego almacena el nombre y finalmente almacena el tipo de valor según el tipo.
La infraestructura de eMule está bien escrita y puede extraerse y reutilizarse fácilmente. El procesamiento con determinadas estructuras de datos, como la codificación de cadenas y las operaciones de E/S de archivos, será muy útil en muchos lugares. La implementación de estas clases en eMule básicamente se copia a otros archivos de proyecto y se puede utilizar rápidamente con ligeras modificaciones. También veremos muchas otras infraestructuras muy útiles en eMule en el futuro.
Como programa para compartir archivos, Emule primero debe tener muy clara la información de todos los archivos que disfruta. Esta es la función de la clase CNownFileList, que se crea en emule.cpp con la creación de la clase cmuleapp.
La clase CNownFileList utiliza la clase CMap de MFC para mantener la tabla hash interna, lo que también muestra que la relación entre emule y MFC es realmente muy estrecha. De hecho, puedes usar mapas STL aquí. Internamente mantiene una lista de archivos conocidos y una lista de archivos cancelados. Las claves de estas tablas hash son los valores hash de los archivos. De esta manera, se pueden determinar archivos con diferentes nombres pero con el mismo contenido. Sin embargo, es muy difícil que archivos con diferentes contenidos tengan el mismo valor hash. Esta es también la intención original del diseño de la función hash. Entonces, a menos que conozcamos a alguien tan increíble como el profesor Wang Xiaoyun, básicamente podemos asumir que dos archivos que tienen el mismo valor hash significa que su contenido es el mismo. Mirando CNownFileList.cpp nuevamente, este archivo en realidad no es largo, porque administrar una lista realmente no requiere muchas operaciones si cada archivo específico tiene una clase poderosa para manejarlo. Aquí hay uno, es CNownFile. Con una clase de este tipo, podemos ver que lo que la clase CNownFileList debe hacer es encontrar la clase CNownFile correspondiente en función de cierta información, copiar la información en otras listas, guardar toda esta información como archivos y luego restaurarla rápidamente la próxima vez. emule ejecuta esta información. Lo más importante es poder completar el trabajo anterior sin provocar pérdidas de memoria.
La clase CNownFile es una clase que presta especial atención a la información sobre un archivo específico. También tiene su clase base CAbstractFile.
Pero la principal diferencia entre esta y la clase CAbstractFile es que la clase CAbstractFile solo tiene funciones básicas de acceso a la información. cknowFile puede generar activamente esta información. Por ejemplo, si le da a cknowFile la ruta a un archivo, puede obtener activamente toda la información relacionada. al archivo y guárdelo en su propia variable miembro (CreateFromFile). El archivo CNownFile.cpp parece más largo porque ha realizado mucho trabajo. En la versión actual de emule, además del hash de texto completo de un archivo, BT también se usa para hash de bloques, de modo que al transferir un archivo, incluso si ocurre un error, no es necesario retransmitir todo el archivo, solo el error ocurre de bloques. Este mecanismo se denomina Manejo Inteligente de la Corrupción Avanzado (AICH, Advanced Intelligent Corruption Handling), que será analizado más adelante.
CNownFile guarda toda la información del archivo leído como etiquetas. Intentará obtener la mayor cantidad de información posible del archivo durante su funcionamiento. Por ejemplo, para archivos de tipo multimedia, puede llamar a la biblioteca id3lib para obtener información de etiquetas como autor, año de lanzamiento y estilo de grabación. Si se trata de un archivo multimedia de vídeo, también se capturará una imagen (implementación de la función: CFrameGrabThread).
CKNowFile también puede conocer el estado de descarga actual del archivo en cualquier momento (hay una lista de CUpDownClient en él) y, por supuesto, se serializará y deserializará según sea necesario. Tanto LoadFromFile como WriteToFile toman CFileDataIO como parámetro para facilitar que CNownFileList guarde y lea información sobre todos los archivos de su lista.