1. Architekturbeschreibung Das aktuelle Protokoll weist die folgenden Merkmale auf:
1) Der Client sendet eine Anfrage an den Server und die Länge jeder Anfrage ist variabel. Die Länge der Anfrage wird im ersten INT angegeben.
2) Jeder Server stellt normalerweise Dienste für mehrere Clients bereit. Beispielsweise muss TS gleichzeitig Dienste für CP und NP bereitstellen.
CP erbringt Dienstleistungen für NP und andere CPs und ist auch Kunde anderer CPs, TS und SPs.
3) Wenn jeder Server einen Client bedient, ist dies normalerweise langfristig und erfordert mehrere Anfragen und Antworten hin und her.
Eine solche Struktur dient hauptsächlich der Unterstützung einer großen Anzahl gleichzeitiger Clientverbindungen. Unabhängig davon, ob Threads oder Prozesse verwendet werden, können keine effektiven Dienste bereitgestellt werden. Daher muss Select verwendet werden
Umfragemodus.
2. Grundlegende Datenstrukturbeschreibung: Für jeden Client müssen einige dem Client entsprechende Informationen gespeichert werden. Aktuelles CPnew.c, SPnew.c
Sie entspricht im Grunde der Kerndatenstruktur von TSnew.c, die aus Sitzung,
Es besteht aus SessionCluster (in TSnew.c) oder ServerDesc (CPnew.c und SPnew.c).
Unter diesen sind Session die Daten zu jedem Client und SessionCluster (oder ServerDesc) die Informationen zu jedem Dienst, die einen Zeiger auf jede mit dem Dienst verbundene Sitzung haben
Diese Datenstruktur wird nicht dynamisch zugewiesen, wenn eine Client-Anfrage vorliegt, sondern wurde bei der Erstinitialisierung zugewiesen. Wenn eine neue Client-Anfrage eingeht, sucht der Server nach diesen vorab zugewiesenen Sitzungen und stellt fest, dass einige inaktive Sitzungen vorhanden sind es, und melden Sie einen Fehler, wenn keine Leerlaufzeit vorhanden ist.
Für TS und CP(SP) besteht der größte Unterschied darin, dass TS das UDP-Protokoll verwendet, während CP und SP das TCP-Protokoll verwenden. Der Unterschied zwischen den beiden ist:
1) Da jeder Client einen anderen Socket verwendet, müssen Sie nach der Auswahl nur überprüfen, ob der fd_set jedes Clients festgelegt ist. Für UDP-Clients müssen Sie den entsprechenden Client finden, den TS verwendet einige Maßnahmen zur Reduzierung des durch die Suche verursachten Overheads.
2) Im TCP-Protokoll liegen die gesendeten Daten in Form eines Streams vor, daher muss die Nachricht in Blöcke unterteilt werden. Es ist möglich, dass zwei Nachrichten in einem Lesevorgang gelesen werden, oder eine Nachricht muss möglicherweise mehrmals gelesen werden Daher müssen beide Situationen berücksichtigt werden: buf, rstart und rlen, die zum Speichern von Nachrichten verwendet werden, die gelesen, aber noch nicht verarbeitet wurden.
Ebenso muss beim Schreibvorgang berücksichtigt werden, dass der Schreibvorgang möglicherweise nicht auf einmal abgeschlossen ist. Daher müssen wbuf, wstart und wlen in jeder Sitzung beibehalten werden. Dies ist in UDP anders Bei der Implementierung wird davon ausgegangen, dass jedes UDP-Paket alle darin enthaltenen Nachrichten vollständig ist, sodass diese Elemente nicht enthalten sind.
SessionCluster (oder ServerDesc) beschreibt einen Dienst, der aus mehreren Hauptteilen besteht:
1) sock: Beschreibt den verwendeten Socket
2) cur: die Anzahl der aktuellen Kunden
3) max: die maximale Anzahl an Clients, die untergebracht werden können
4) Kopf: Kopf der Sitzung, Kopf[0] ist die erste Sitzung, Kopf[max-1] ist die letzte Sitzung
5) init: Der Initialisierungsvorgang, der von jeder Sitzung in diesem Dienst ausgeführt werden muss (Funktionszeiger).
6) Prozess: die Verarbeitungsfunktion von Nachrichten in diesem Dienst
7) Schließung: der für diesen Dienst erforderliche Destruktor
3. Beschreibung der Hauptstruktur
Process_child: Hauptfunktion, diese Funktion wird hauptsächlich zum Festlegen von Socken und Wsocks verwendet. Für SP und CP wird Wsocks nur festgelegt, wenn Wlen von Sitzung> 0 ist.
wählen;
Für jeden ServerDesc (oder SessionCluster) gilt: process_type
In SP und CP muss zur Unterstützung der PUSHLIST-Operation vor jedem Zyklus „processJob“ ausgeführt werden.
In CP wird periodCheck auch regelmäßig durchgeführt, um abgelaufene Verbindungen in TS zu löschen, und periodLog wird regelmäßig durchgeführt, um abgelaufene Kundenverbindungen zu löschen.
Prozesstyp:
Überprüfen Sie für jede Sitzung, ob sie lesbar ist. Überprüfen Sie, ob eine vollständige Nachricht vorliegt.
*(unsigned int *)(rbuf+rstart) <= rlen
Rufen Sie den entsprechenden Prozess auf, bis keine vollständige Nachricht vorliegt, um zu prüfen, ob sie beschreibbar ist und wlen>0 ist, schreiben Sie
4. Weitere wichtige Module
1) Konfigurationsmodul Das Konfigurationsmodul besteht hauptsächlich aus den Strukturen NamVal, read_config und free_config.
Name ist der Name in der CFG-Datei, ptr ist der Zeiger auf den Speicher und Typ ist der Datentyp. Derzeit werden die folgenden Typen unterstützt
d: Integer-Typ, ptr ist ein Integer-Zeiger
s: String-Typ, ptr ist ein Zeiger auf einen Zeiger, (char **)
b: String-Puffertyp, ptr ist ein char *, Sie sollten bei der Verwendung dieses Typs darauf achten, für s-Typ,
read_config reserviert Speicher (malloc) für val, aber für Typ b muss ptr auf den zugewiesenen Speicher verweisen.
Die beiden wichtigen Funktionen sind:
read_config, die Parameter sind der Dateiname, eine Struktur NamVal * und die Anzahl der Elemente der Struktur NamVal
free_config, die Parameter sind die gleichen wie struct NamVal * und die Anzahl der Elemente wie read_config
2) MySQL-Modul
Das MySQL-Modul besteht hauptsächlich aus MYSQL *local_mysql und drei Funktionen
init_mysql, initialisiert MySQL, gibt ein MYSQL * zurück und wird im Allgemeinen zum Initialisieren von local_mysql verwendet
query_mysql, führen Sie eine MySQL-Anweisung aus, das Format ist query_mysql (local_mysql, „MySQL-Anweisung,
Das Format ist das gleiche wie das von printf, z. B. „Löschen aus %s“ usw. (erforderlicher Wert).
query_mysql_select führt eine MySQL-Select-Anweisung aus. Anders als oben wird eine zurückgegeben
MYSQL_RES *.
3) Das Netzwerksortiermodul besteht hauptsächlich aus der Netzwerkstruktur, der readNETBLOCK-Funktion, der getnetwork-Funktion und der CompareNet-Funktion.
readNETBLOCK wird verwendet, um die Netzwerkkonfigurationsdatei zu lesen und die globale Variable NETBLOCKS zu initialisieren
Array der Netzwerkstruktur mit MAX_NET-Elementen.
getnetowrk wird verwendet, um den Netblock zu finden, der einer IP-Adresse am nächsten liegt
CompareNet ist eine Funktion, die in qsort verwendet wird, um die gefundenen NPPeers so zu sortieren, dass NPPeers im selben Netzwerk an erster Stelle stehen.
4) Diagrammverwaltung Im aktuellen CP, SP und NP kann CP mehrere Kanäle gleichzeitig verbinden, und NP kann auch über mehrere Ressourcen verfügen. Um diese Struktur zu beschreiben, wird das Konzept des Diagramms eingeführt ) wird gespeichert Ein Zeiger auf NP, ein Zeiger auf Kanal,
In TS ist es außerdem erforderlich, jedes Intervall dieser Sitzung in diesem Kanal zu speichern
Der cnext wird in eine verknüpfte Liste eingefügt. Der Kopf dieser verknüpften Liste ist der PeerHead in der Kanalstruktur und in jeder Sitzung
Der Enext in Edge wird ebenfalls in eine verknüpfte Liste eingefügt, und der Kopf dieser verknüpften Liste ist der Header in der Sitzungsstruktur.
Verwandte Funktionen sind:
newEdge: Fügen Sie eine neue Kante hinzu. Die Parameter sind Channel *, Session *. Für TS ist eine ChannelInfo erforderlich, um die Informationen in Edge zu initialisieren.
delEdge: Eine Kante löschen, der Parameter ist Edge *
5) Kanalmodul
Die Hauptfunktionen des Channel-Moduls sind:
TS wird zur Verarbeitung von NEED_PEERS verwendet, SP muss außerdem Kanaldaten speichern und durchsuchen und Kanäle werden mithilfe von Diagrammstrukturen verwaltet.
Die Kanalsuche verwendet aus Effizienzgründen Hash. ChannelHash verwendet Zeichenfolgen.
Hash, wie in hash_str gezeigt.
Channel in TS ist relativ einfach. Channel in SP und CP müssen auch kanalbezogene Daten verwalten. Diese Daten werden in Form von Dateien im Verzeichnis /var/tmp/ gespeichert. Für jede relevante Information
Gespeichert durch BlockData, Firstsample, Message_Size, Message_ID und Offset in BlockData. Speichern Sie Firstsample-Informationen, Blocklänge, Block-ID und Offset in der Datei.
Die Verarbeitung von SP und CP ist unterschiedlich. Bei CP ist die Block-ID beispielsweise 1000
max_queue ist 100, dann ist der Speicherort 1000 % 100 = 0. Wenn die Ressource für SP ein von CS gesendeter Kanal ist,
Es handelt sich um eine kreisförmige Warteschlange, und jeder Block wird der Reihe nach an der entsprechenden Position gespeichert. Wenn er das Ende der Warteschlange erreicht, beginnt er am Kopf der Warteschlange. Wenn es sich bei der Ressource um eine Datei handelt, werden die BlockData-Informationen nicht gespeichert. und die Originaldatei befindet sich direkt entsprechend der BlockID.
Es gibt viele Funktionen, an denen Channel beteiligt ist, z. B. „locate_by_id“, „locate_order_by_id“, „newChannel“ usw.
freeChannel, saveBlock usw.
6) Das Berkeley DB-Modul ist nur an SP beteiligt. Es öffnet hauptsächlich DB-Dateien und fragt den Speicherort eines bestimmten MD5 ab. Es handelt sich hauptsächlich um DB* MediaDB.
Die beiden Funktionen openDB und openMedia
openDB: Der Parameter ist der Name der DB-Datei
openMedia: Die Parameter sind MD5 und ein Ganzzahlzeiger. Geben Sie FILE * und die Länge der Datei im Ganzzahlzeiger zurück
7) Jobmodul
Das Job-Modul wird in CP und SP zur Verarbeitung von PUSHLIST verwendet. Die PUSHLIST-Nachricht kann die Jobliste zurücksetzen.
Sie können auch einen Job hinzufügen oder löschen. Dazu gehören die Funktionen in job.c und die JobDes-Struktur. Eine Sitzung * und ein Kanal * in der JobDes-Struktur werden verwendet, um die Sitzung und den Kanal zu identifizieren, zu denen der Job gehört num stellt die Anzahl der BlockIDs dar, die heruntergeladen werden müssen, job ist ein Zeiger auf eine Ganzzahl, mask ist auch ein Zeiger auf eine Ganzzahl.
job[i] ist die BlockID, die heruntergeladen werden muss. Wenn mask[i] 0 ist, muss sie heruntergeladen werden. Wenn sie 1 ist, wird sie nicht benötigt.
addJob: Beim Hinzufügen eines Jobs wird nicht geprüft, ob der Job bereits in der Liste vorhanden ist, sondern es wird direkt ein Job generiert und zur verknüpften Liste hinzugefügt.
deleteJob: Überprüfen Sie beim Löschen eines Jobs alle Jobs in der Jobliste auf Jobs mit derselben Sitzung und demselben Kanal.
Setzen Sie dann die entsprechende Maske der zu löschenden BlockID auf 1.
ProcessJob: Verwenden Sie für jeden Job, beginnend mit cur, Process_P2P_REQUEST_real, um den ersten Block mit Maske 0 zu übertragen. Wenn alle 1 sind, löschen Sie den Job.
freeJob: Eine JobDes löschen.
freeJobList: Alle JobDes einer Sitzung löschen, wird normalerweise verwendet, wenn die Sitzung beendet wird.
8) Intervallmodul
Das Intervallmodul wird in TS verwendet, um alle schnellen Intervalle auf NP darzustellen. Derzeit wird das Blockintervall durch ein Startfeld und ein Längenfeld identifiziert. Die Hauptoperationen für Intervall sind Zusammenführen und Löschen
Es kombiniert das ursprüngliche Intervall und die neue Intervallliste, während durch Löschen das neue aus dem Original entfernt wird.
merge: Der Algorithmus lautet wie folgt und verwendet die Pufferintervallliste tmp.
if (old[i] < new[j]) tmp[k] = old[i];
sonst tmp[k] = new[j];
Schauen Sie sich dann an, was von Alt und Neu mit tmp[k] zusammengeführt werden kann.
Löschen: ist komplizierter. Berücksichtigen Sie die folgenden Situationen
Der Anfang von alt[i] ist größer als das Ende von neu[j]
Das Ende von old[i] liegt vor dem Beginn von new[j]
old[i] und new[j] haben gemeinsame Teile und
old[i] ist in new[j] enthalten
new[j] ist in old[i] enthalten und schließt einander nicht ein, new[j] ist in dem vorherigen enthalten und schließt einander nicht ein, und old[i] ist in dem vorherigen enthalten.
5. Einige schnelle Algorithmen
1) Wenn sich der Client zum ersten Mal bei TS anmeldet, muss er eine inaktive Sitzung finden. Darüber hinaus sendet der Client möglicherweise wiederholt LOGIN-Nachrichten bereits in der Sitzungsliste: Wenn der Client eine Nachricht sendet, muss er die entsprechende Sitzung finden.
Um diese Abfragen zu vermeiden, werden jeweils die folgenden Methoden verwendet.
Erstellen Sie zunächst eine Hash-Tabelle. Immer wenn ein neuer Client eintrifft, wird die Sitzung aus Hash[0] entnommen und mit dem entsprechenden Hash verknüpft Der durch Hash erhaltene Wert darf nicht 0 sein. Wenn er 0 ist, wird der größtmögliche Hash-Hid zurückgegeben.
Beim Abfragen der Sitzung basierend auf dem Quellport und der IP-Adresse wird ebenfalls diese Hash-Tabelle verwendet.
Wenn der Client eine Nachricht sendet, verwendet er die ersten 3 Bytes der 7 Bytes, die zur Überprüfung verwendet werden, und verwendet diese 3 Bytes zur Identifizierung der Sitzung.
tiefgestellt, wodurch der Abfrageaufwand vermieden wird.
2) Verwenden Sie maxid, um die Anzahl der Suchvorgänge zu reduzieren.
Hash wird in TCP nicht verwendet, um die größte ID in der Sitzung aufzuzeichnen
Während der Initialisierung wird nach der inaktiven Sitzung mit der kleinsten ID gesucht, sodass die Sitzung als relativ kompakt betrachtet werden kann.
Da SP und CP weitaus weniger Clients unterstützen als TS, ist diese Behandlung akzeptabel.
Wenn der Kunde aussteigt, kann es erforderlich sein, die Maxid zu aktualisieren. Diese Aktualisierung wird durch Clientclosure abgeschlossen.
Clientclosure aktualisiert maxid und ruft dann den entsprechenden Destruktor auf.
3) Timeout-Verarbeitung von langfristig inaktiven Verbindungen, da die Timeout-Verarbeitung das Durchlaufen der gesamten Liste erfordert, um Systemressourcen zu sparen.
Darüber hinaus dauert die Meldung von Systemstatistiken im Allgemeinen sehr lange, daher ist Aktualität erforderlich.
Im Allgemeinen bestimmen periodLog oder periodCheck, welche der beiden Operationen ausgeführt werden sollen.
4) Bei der Abfrage von CPPeer wird unter Berücksichtigung der Tatsache, dass derzeit nur GCP unterstützt wird, GCPCHOICE direkt verwendet, auf das GCP mit der geringsten aktuellen Auslastung festgelegt und aktualisiert, wenn GCP meldet oder sich GCP an- und abmeldet.
6. Nachrichtenverarbeitung
1) TS-Nachrichtenverarbeitung
NP2TS_LOGIN: NP meldet sich bei TS an und hasht entsprechend der Quell-IP-Adresse und dem gemeldeten NP-Port. Wenn die Zeit seit dem letzten Senden der NP2TS_LOGIN-Nachricht kürzer als SILENCE_TIME ist, wird direkt zurückgegeben, andernfalls wird eine WELCOME-Nachricht gesendet.
NP2TS_REPORT: Informationen zum Berichtsintervall werden zurückgesetzt, andernfalls werden sie zuerst hinzugefügt und dann gelöscht.
NP2TS_NEED_PEERS: Peer-Informationen abfragen, findCPPeer verwenden, um einen geeigneten CP zu finden, findNPPeers verwenden
Suchen Sie nach einem geeigneten NP. Bei der Suche nach NP werden die Ergebnisse nach Netzwerken sortiert, um sicherzustellen, dass diejenigen im selben Netzwerk an erster Stelle stehen.
NP2TS_LOGOUT: Beenden
NP2TS_RES_LIST: Senden Sie alle RESSOURCEN des aktuellen NP, verwenden Sie addSession zur Verarbeitung. Wenn diese Kante noch nicht vorhanden ist, fügen Sie sie hinzu
NP2TS_REQ_RES: RES hinzufügen und Peers zurückgeben
NP2TS_DEL_RES: RES löschen
CP2TS_REGISTER: Anmelden, CP meldet sich bei TS an, Hashes entsprechend der Quell-IP-Adresse und dem gemeldeten npport,
Wenn seit dem letzten Senden von CP2TS_REGISTER ILENCE_TIME vergangen ist, kehren Sie direkt zurück, andernfalls senden Sie
WILLKOMMEN-Nachricht.
CP2TS_UPDATE: CP-Last melden
CP2TS_NEED_PEERS: Wird für die ECP-Abfrage verwendet, noch nicht verwendet
2) SP-Nachrichtenverarbeitung
P2P_HELLO: Tritt einem Kanal bei,
Wenn der Kanal vorhanden ist und es sich um eine Mediendatei handelt: Geben Sie SPUPDATE zurück und geben Sie die minimale und maximale Block-ID dieses Kanals an
Andernfalls: Wenn dieser Kanal beendet wurde, geben Sie die Endinformationen zurück. Wenn der Kanal nicht vorhanden ist und es sich um eine Mediendatei handelt: Geben Sie SPUPDATE zurück und geben Sie die minimale und maximale Block-ID dieses Kanals an. Andernfalls: Geben Sie ein SPUPDATE zurück weisen auf einen Fehler hin.
P2P_PUSHLIST: Aufgabenliste zurücksetzen oder hinzufügen oder löschen. Beim Zurücksetzen zuerst alle zugehörigen Aufgaben löschen und dann hinzufügen oder löschen.
CS2SP_REGISTER: Kanal erstellen
CS2SP_UPDATE: Kanalinformationen aktualisieren
CS2SP_BLOCK: Datenblock senden
3) CP-Nachrichtenverarbeitung
P2P_HELLO: Treten Sie einem Kanal bei und stellen Sie eine entsprechende Verbindung basierend auf der bereitgestellten SP-Adresse her
P2P_PUSHLIST: Aufgabenliste zurücksetzen oder hinzufügen und löschen
P2P_SPUPDATE: Das vom SP gesendete SPUPDATE wird nicht an NP weitergeleitet, wenn es sich um eine Mediendatei handelt
P2P_RESPONSE: Vom SP gesendeter Datenblock.
Darüber hinaus muss sich CP auch bei TS registrieren.
Derzeit wird nur ein GCP-Typ verwendet.
Expandieren