1. Descripción de la Arquitectura El protocolo actual tiene las siguientes características:
1) El cliente envía una solicitud al servidor y la longitud de cada solicitud es variable. La longitud de la solicitud se especifica en el primer INT.
2) Cada servidor generalmente brinda servicios a múltiples clientes. Por ejemplo, TS necesita brindar servicios a CP y NP al mismo tiempo.
CP proporciona servicios a NP y otros CP, y también es cliente de otros CP, TS y SP.
3) Cuando cada servidor atiende a un cliente, suele ser a largo plazo e implica múltiples solicitudes y respuestas de un lado a otro.
Dicha estructura está diseñada principalmente para admitir una gran cantidad de conexiones de clientes simultáneas. Cuando hay una gran cantidad de conexiones de clientes simultáneas, no se pueden proporcionar servicios efectivos sin importar si se utilizan subprocesos o procesos, por lo que se debe utilizar select.
Modo de sondeo.
2. Descripción de la estructura de datos básica: para cada cliente, se debe guardar cierta información correspondiente al cliente CPnew.c, SPnew.c actual.
Es básicamente la misma que la estructura de datos central de TSnew.c, que consta de sesión,
Consiste en SessionCluster (en TSnew.c) o ServerDesc (CPnew.c y SPnew.c).
Entre ellos, Session son los datos relacionados con cada cliente y SessionCluster (o ServerDesc) es la información sobre cada servicio, que tiene un puntero a cada sesión relacionada con el servicio.
Esta estructura de datos no se asigna dinámicamente cuando hay una solicitud de cliente, pero se asigna en la inicialización inicial. Cuando llega una nueva solicitud de cliente, el servidor busca estas sesiones preasignadas y encuentra que hay algunas inactivas. e informar un error si no hay tiempo de inactividad.
Para TS y CP (SP), la mayor diferencia es que TS usa el protocolo UDP, mientras que CP y SP usan el protocolo TCP. La diferencia entre los dos es:
1) Para los clientes del protocolo TCP, dado que cada cliente usa un socket diferente, después de seleccionar, solo necesita verificar si el fd_set de cada cliente está configurado. Para los clientes UDP, debe encontrar el cliente correspondiente. algunas medidas para reducir los gastos generales causados por la búsqueda.
2) En el protocolo TCP, los datos enviados están en forma de flujo, por lo que el mensaje debe dividirse en bloques. Es posible que se lean dos mensajes en una sola lectura, o es posible que sea necesario leer un mensaje muchas veces. Es necesario considerar ambas situaciones. Por lo tanto, cada sesión tiene un buf, rstart y rlen, que se utilizan para almacenar mensajes que se han leído pero que aún no se han procesado.
De manera similar, durante el proceso de escritura, también es necesario considerar que es posible que la escritura no se complete de una vez, por lo que también es necesario conservar wbuf, wstart y wlen en cada sesión. Esto es diferente en UDP. Implementación, se supone que cada paquete UDP Los mensajes contenidos en están todos completos, por lo que estos elementos no están incluidos.
SessionCluster (o ServerDesc) describe un servicio que consta de varias partes principales:
1) calcetín: describe el encaje utilizado
2) cur: el número de clientes actuales
3) max: el número máximo de clientes que se pueden acomodar
4) head: Jefe de sesión, head[0] es la primera sesión, head[max-1] es la última sesión
5) init: la operación de inicialización que debe realizar cada sesión en este servicio (puntero de función).
6) proceso: la función de procesamiento de mensajes en este servicio
7) cierre: el destructor requerido en este servicio
3. Descripción de la estructura principal
Process_child: función principal, esta función se usa principalmente para configurar calcetines y wsocks. Para SP y CP, wsocks solo se configura cuando wlen de Sesión>0;
seleccionar;
Para cada ServerDesc (o SessionCluster), tipo_proceso
En SP y CP, para admitir la operación PUSHLIST, se debe realizar ProcessJob antes de cada ciclo.
En CP, periodCheck también se realiza periódicamente para borrar las conexiones caducadas en TS, y periodLog se realiza periódicamente para borrar las conexiones caducadas de los clientes.
tipo_proceso:
Para cada sesión, verifique si es legible. Si es legible, verifique si hay un mensaje completo.
*(int sin signo *)(rbuf+rstart) <= rlen
Llame al proceso correspondiente hasta que no haya ningún mensaje completo para verificar si se puede escribir. Si se puede escribir y wlen>0, escriba.
4. Otros módulos importantes
1) Módulo de configuración El módulo de configuración consta principalmente de struct NamVal, read_config, free_config En la estructura NamVal,
Nombre es el nombre en el archivo cfg, ptr es el puntero al almacenamiento y tipo es el tipo de datos. Actualmente, se admiten los siguientes tipos.
d: tipo entero, ptr es un puntero entero
s: tipo de cadena, ptr es un puntero a un puntero, (char **)
b: tipo de búfer de cadena, ptr es un char *, debe prestar atención al usar este tipo, para el tipo s,
read_config asignará memoria (malloc) para val, pero para el tipo b, ptr debe apuntar a la memoria asignada.
Las dos funciones importantes son:
read_config, los parámetros son el nombre del archivo, una estructura NamVal * y el número de elementos de la estructura NamVal
free_config, los parámetros son la misma estructura NamVal * y el número de elementos que read_config
2) módulo mysql
El módulo mysql consta principalmente de MYSQL *local_mysql y tres funciones.
init_mysql, inicializa mysql, devuelve un MYSQL *, generalmente usado para inicializar local_mysql
query_mysql, ejecuta una declaración mysql, el formato es query_mysql (local_mysql, "declaración mysql,
El formato es el mismo que el de printf, como eliminar de %s, etc.", el valor requerido)
query_mysql_select, ejecuta una declaración de selección de mysql. A diferencia de lo anterior, devuelve una.
MYSQL_RES*.
3) El módulo de clasificación de redes se compone principalmente de la estructura de redes, la función readNETBLOCK, la función getnetwork y la función compareNet, entre las cuales,
readNETBLOCK se utiliza para leer el archivo de configuración de red e inicializar la variable global NETBLOCKS es un.
Matriz de estructura de redes, con elementos MAX_NET.
getnetowrk se utiliza para encontrar el bloque de red más cercano a una dirección IP
compareNet es una función utilizada en qsort para ordenar los NPPeers encontrados de modo que los NPPeers de la misma red ocupen el primer lugar.
4) Gestión de gráficos En los CP, SP y NP actuales, CP puede unir múltiples canales al mismo tiempo y NP también puede tener múltiples recursos. Para describir esta estructura, se introduce el concepto de gráfico. ) se almacena Un puntero a NP, un puntero a Canal,
En TS, también es necesario almacenar cada intervalo de esta sesión en este canal. Cada canal pasa por Edge.
El siguiente in está encadenado en una lista vinculada. El encabezado de esta lista vinculada es el PeerHead en la estructura del Canal y cada Sesión.
El siguiente en Edge también está incluido en una lista vinculada, y el encabezado de esta lista vinculada es el encabezado en la estructura de la sesión.
Las funciones relacionadas son:
newEdge: agrega un nuevo borde, los parámetros son Canal *, Sesión *. Para TS, se necesita ChannelInfo para inicializar la información en Edge.
delEdge: elimina un borde, el parámetro es Edge *
5) módulo de canal
Las principales funciones del módulo Canal son:
TS se usa para procesar NEED_PEERS, SP también necesita guardar y buscar datos del canal, y los canales se administran mediante estructuras gráficas.
La búsqueda de canales usa Hash por razones de eficiencia. ChannelHash usa cadenas.
hash, como se muestra en hash_str.
El canal en TS es relativamente simple. El canal en SP y CP también necesita administrar datos relacionados con el canal. Estos datos se almacenan en el directorio /var/tmp/ en el disco duro. Los nombres de los archivos se generan aleatoriamente. Para cada pieza de información relevante,
Guardado por BlockData, firstsampl, message_size, message_id y offset en BlockData almacenan la información de la primera muestra, la longitud del bloque, la identificación del bloque y el desplazamiento en el archivo respectivamente.
El procesamiento de SP y CP es diferente. Para CP, los bloques se almacenan en modo hash. Por ejemplo, el ID del bloque es 1000.
max_queue es 100, entonces la ubicación de almacenamiento es 1000%100=0. Para SP, si el recurso es un canal enviado por CS,
Es una cola circular y cada bloque se almacena en la posición correspondiente en orden. Si llega al final de la cola, comienza desde el principio de la cola. Si el recurso es un archivo, la información de BlockData no se guarda. y el archivo original se ubica directamente según el blockID.
Hay muchas funciones que involucran Channel, como localizar_by_id, localizar_order_by_id, newChannel,
freeChannel, saveBlock, etc.
6) El módulo Berkeley DB solo está involucrado en SP. Principalmente abre archivos DB y consulta la ubicación de un determinado md5. Implica principalmente DB * MediaDB.
Las dos funciones openDB y openMedia
openDB: el parámetro es el nombre del archivo DB
openMedia: Los parámetros son md5 y un puntero entero, devuelve ARCHIVO * y la longitud del archivo, en el puntero entero
7) Módulo de trabajo
El módulo de trabajo se utiliza en CP y SP para procesar PUSHLIST. El mensaje PUSHLIST puede restablecer la lista de trabajos.
También puede agregar un trabajo o eliminar un trabajo. Implica las funciones en job.c y la estructura JobDes. Se utilizan una sesión * y un canal * en la estructura JobDes para identificar la sesión y el canal al que pertenece el trabajo. num representa la cantidad de BlockID que deben descargarse, el trabajo es un puntero a un número entero y la máscara también es un puntero a un número entero.
job[i] es el BlockID que debe descargarse. Si la máscara[i] es 0, debe descargarse. Si es 1, no es necesaria.
addJob: al agregar un trabajo, no verifica si el trabajo ya está en la lista, sino que genera un trabajo directamente y lo agrega a la lista vinculada.
eliminarTrabajo: al eliminar un trabajo, verifique todos los trabajos en la lista de trabajos para ver si tienen la misma sesión y canal.
Luego configure la máscara correspondiente del ID de bloque que debe eliminarse en 1.
ProcessJob: para cada trabajo, comenzando desde cur, use Process_P2P_REQUEST_real para transmitir el primer bloque con máscara 0. Si todos son 1, elimine el trabajo.
freeJob: Elimina un JobDes.
freeJobList: elimina todos los JobDes de una sesión, generalmente se usa cuando sale la sesión.
8) módulo de intervalo
El módulo Interval se utiliza en TS para representar todos los intervalos rápidos en NP. Actualmente, el intervalo de bloque se identifica mediante un campo de inicio y un campo de longitud. Las operaciones principales de Interval son fusionar, eliminar y fusionar.
Combina el intervalo original y la nueva lista de intervalos, mientras que eliminar elimina el nuevo del original.
fusionar: el algoritmo es el siguiente, utilizando la lista de intervalos de búfer tmp.
if (antiguo[i] < nuevo[j]) tmp[k] = antiguo[i];
else tmp[k] = nuevo[j];
Luego mire cuál de lo antiguo y lo nuevo se puede fusionar con tmp[k]
eliminar: es más complicado, considere las siguientes situaciones
El comienzo de lo antiguo[i] es mayor que el final de lo nuevo[j]
El final de lo antiguo[i] es antes del comienzo de lo nuevo[j]
antiguo[i] y nuevo[j] tienen partes comunes, y
antiguo[i] está contenido en nuevo[j]
new[j] está incluido en old[i] y no se incluyen entre sí, new[j] está incluido en el anterior y no se incluyen entre sí, y old[i] está incluido en el anterior.
5. Algunos algoritmos rápidos
1) En TS que usa UDP, cuando el cliente inicia sesión por primera vez, es necesario encontrar una sesión inactiva. Además, el cliente puede enviar mensajes de INICIO de sesión repetidamente. En este caso, es necesario verificar si el cliente está inactivo. Ya está en la lista de sesiones. En tercer lugar, cuando el cliente envía un mensaje, necesita encontrar la sesión correspondiente.
Para evitar estas consultas, se utilizan los siguientes métodos respectivamente.
Primero, cree una tabla Hash. Al principio, todas las sesiones gratuitas están vinculadas a Hash [0]. Cada vez que llega un nuevo cliente, la sesión se extrae de Hash [0] y se vincula al hashid correspondiente. El valor obtenido por hash no puede ser 0. Si es 0, se devuelve el hashid más grande posible.
La consulta de la sesión en función del puerto de origen y la dirección IP también utiliza esta tabla Hash.
Cuando el cliente envía un mensaje, utiliza los primeros 3 bytes de los 7 bytes utilizados para la verificación y utiliza estos 3 bytes para identificar la sesión.
subíndice, evitando así la sobrecarga de consultas.
2) Utilice maxid para reducir el número de búsquedas.
Hash no se usa en TCP. El elemento maxid se usa para registrar la identificación más grande en la sesión desde la sesión.
Durante la inicialización, se busca la sesión inactiva con el ID más pequeño, por lo que la sesión puede considerarse relativamente compacta.
Dado que SP y CP apoyan a muchos menos clientes que TS, este tratamiento es aceptable.
Cuando el cliente sale, puede que sea necesario actualizar el maxid. Esta actualización se completa mediante Clientclosure.
Clientclosure actualiza maxid y luego llama al destructor correspondiente.
3) Procesamiento de tiempo de espera de conexiones inactivas a largo plazo. Dado que el procesamiento de tiempo de espera requiere recorrer toda la lista, para ahorrar recursos del sistema,
IDLE lleva mucho tiempo. Además, las estadísticas del sistema generalmente deben informarse con regularidad, por lo que se requiere puntualidad.
Generalmente, periodLog o periodCheck determinan cuál de las dos operaciones se realizará.
4) Al consultar CPPeer, considerando que actualmente solo se admite GCP, GCPCHOICE se usa directamente, se configura en el GCP con la carga actual más pequeña y se actualiza cuando GCP informa o inicia y cierra sesión.
6. Procesamiento de mensajes
1) procesamiento de mensajes TS
NP2TS_LOGIN: NP inicia sesión en TS y aplica hash de acuerdo con la dirección IP de origen y el npport informado. Si el tiempo desde la última vez que se envió el mensaje NP2TS_LOGIN es menor que SILENCE_TIME, regresa directamente; de lo contrario, se envía un mensaje de BIENVENIDA.
NP2TS_REPORT: información del intervalo de informe. Si la actualización es verdadera, se restablecerá. De lo contrario, se agregará primero y luego se eliminará.
NP2TS_NEED_PEERS: consulta información de pares, use findCPPeer para encontrar un CP adecuado, use findNPPeers
Busque un NP adecuado Al buscar NP, después de encontrar los resultados, se ordenan por redes para garantizar que aquellos en la misma red ocupen el primer lugar.
NP2TS_LOGOUT: Salir
NP2TS_RES_LIST: envía todos los RECURSOS del NP actual, usa addSession para procesar, si este borde aún no existe, agrégalo
NP2TS_REQ_RES: Agregar RES y devolver pares
NP2TS_DEL_RES: Eliminar RES
CP2TS_REGISTER: inicie sesión, CP inicia sesión en TS, aplica hash de acuerdo con la dirección IP de origen y el npport informado,
Si es ILENCE_TIME desde la última vez que se envió CP2TS_REGISTER, regrese directamente; de lo contrario, envíe
Mensaje de BIENVENIDA.
CP2TS_UPDATE: Informar carga de CP
CP2TS_NEED_PEERS: usado para consulta ECP, aún no usado
2) procesamiento de mensajes SP
P2P_HELLO: Únete a un canal,
Si el canal existe, si es un archivo Media: Retorna SPUPDATE, indicando el blockID mínimo y máximo de este canal
De lo contrario: Si este canal ha finalizado, devuelve la información de finalización. Si el canal no existe, si es un archivo multimedia: Devuelve SPUPDATE, indicando el ID de bloque mínimo y máximo de este canal, crea el canal. De lo contrario: Devuelve un SPUPDATE a. indicar un error.
P2P_PUSHLIST: Restablecer o agregar o eliminar la lista de tareas Al restablecer, elimine primero todas las tareas relacionadas y luego agregue o elimine.
CS2SP_REGISTER: Crear canal
CS2SP_UPDATE: Actualizar información del canal
CS2SP_BLOCK: Enviar bloque de datos
3) procesamiento de mensajes CP
P2P_HELLO: Únase a un canal y establezca la conexión correspondiente según la dirección SP proporcionada
P2P_PUSHLIST: restablecer o agregar y eliminar la lista de tareas
P2P_SPUPDATE: SPUPDATE enviado por SP, si es un archivo multimedia, no se reenviará a NP
P2P_RESPONSE: Bloque de datos enviado por SP.
Además, CP también debe registrarse en TS.
Actualmente sólo se utiliza un tipo de GCP.
Expandir