Heim  >  Artikel  >  Java  >  Grafische Einführung in die Protokolle TCP, UDP und IP in Java

Grafische Einführung in die Protokolle TCP, UDP und IP in Java

黄舟
黄舟Original
2017-07-21 16:12:412112Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Informationen zur TCP-, UDP- und IP-Protokollanalyse ausführlich vorgestellt. Interessierte Freunde können darauf verweisen.

In den Anfängen des Internets Die Verbindung zwischen ihnen erfolgt über das NCP-Protokoll. Dieses Protokoll selbst weist viele Mängel auf, wie zum Beispiel: Es kann keine verschiedenen Hosts miteinander verbinden, es kann keine verschiedenen Betriebssysteme miteinander verbinden und es verfügt über keine Fehlerkorrekturfunktion. Um diesen Mangel zu beheben, entwickelte Daniel das TCP/IP-Protokoll. Fast alle Betriebssysteme implementieren mittlerweile den TCP/IP-Protokollstapel.

Der TCP/IP-Protokollstapel ist hauptsächlich in vier Schichten unterteilt: Anwendungsschicht, Transportschicht, Netzwerkschicht und Datenverbindungsschicht. Jede Schicht verfügt über ein entsprechendes Protokoll, wie unten gezeigt


Das sogenannte Protokoll ist ein Format zur Datenübertragung zwischen beiden Parteien. Es gibt viele Protokolle, die im gesamten Netzwerk verwendet werden, und glücklicherweise verfügt jedes Protokoll über ein RFC-Dokument. Hier führen wir nur eine Analyse der IP-, TCP- und UDP-Protokollheader durch.

Werfen wir zunächst einen Blick auf das Format eines Ethernet-Pakets im Netzwerk:


Im Linux-Betriebssystem Wenn wir Daten senden möchten, müssen wir die Daten nur in der oberen Schicht vorbereiten und sie dann an den Kernel-Protokollstapel senden. Der Kernel-Protokollstapel fügt dann automatisch den entsprechenden Protokollheader hinzu. Werfen wir einen Blick auf den spezifischen Inhalt des auf jeder Ebene hinzugefügten Protokollheaders.

1. TCP-Protokoll

Das TCP-Protokoll ist verbindungsorientiert und gewährleistet eine hohe Zuverlässigkeit (kein Datenverlust, keine Datenstörung, kein Datenfehler). ) , kein doppeltes Eintreffen von Daten) Transportschichtprotokoll.

1.TCP-Header-Analyse

Lassen Sie uns zunächst das Format des TCP-Headers und die Bedeutung jedes Felds analysieren:


(1) Portnummer [16bit]

Wir wissen, dass das Netzwerk eine prozessübergreifende Kommunikation zwischen verschiedenen Hosts implementiert. In einem Betriebssystem gibt es viele Prozesse, wenn Daten zur Verarbeitung übermittelt werden. Dies erfordert die Verwendung von Portnummern. Im TCP-Header gibt es die Quellportnummer (Source Port) und die Zielportnummer (Destination Port). Die Quellportnummer identifiziert den Prozess des sendenden Hosts und die Zielportnummer identifiziert den Prozess des empfangenden Hosts.

(2) Sequenznummer [32bit]

Die Sequenznummer ist in Sendesequenznummer (Sequenznummer) und Bestätigungssequenznummer (Bestätigungsnummer) unterteilt.

Sendesequenznummer: Wird zur Identifizierung des von der TCP-Quelle an das TCP-Ziel gesendeten Datenbytestroms verwendet. Sie gibt die Sequenznummer des ersten Datenbytes in diesem Nachrichtensegment an. Wenn Sie sich einen Bytestrom als einen unidirektionalen Fluss zwischen zwei Anwendungen vorstellen, zählt TCP jedes Byte mit einer Sequenznummer. Die Seriennummer ist eine 32-Bit-Zahl ohne Vorzeichen. Die Seriennummer beginnt bei 0, nachdem sie 2 32-1 erreicht hat. Wenn eine neue Verbindung hergestellt wird, ändert sich das SYN-Flag auf 1 und das Sequenznummernfeld enthält die anfängliche Sequenznummer ISN (Initial Sequence Number), die von diesem Host für die Verbindung ausgewählt wurde.

Bestätigungssequenznummer: Enthält die nächste Sequenznummer, die das Ende, das die Bestätigung sendet, erwartet. Daher sollte die Bestätigungssequenznummer die letzte erfolgreich empfangene Datenbyte-Sequenznummer plus 1 sein. Das Bestätigungssequenznummernfeld ist nur gültig, wenn das ACK-Flag 1 ist. TCP stellt der Anwendungsschicht Vollduplex-Dienste zur Verfügung, was bedeutet, dass Daten unabhängig in beide Richtungen übertragen werden können. Daher muss jedes Ende der Verbindung die Sequenznummer der übertragenen Daten in jede Richtung beibehalten.

(3) Offset [4bit]

Der Offset bezieht sich hier tatsächlich auf die Länge des TCP-Headers, der zur Angabe der 32-Bit-Länge verwendet wird Wort im TCP-Header Nummer, anhand derer Sie erkennen können, wo die Benutzerdaten eines TCP-Pakets beginnen. Dieses Feld belegt 4 Bits. Wenn der Wert von 4 Bits 0101 ist, bedeutet dies, dass die TCP-Header-Länge 5 * 4 = 20 Bytes beträgt. Die maximale Header-Länge von TCP beträgt also 15 * 4 = 60 Bytes. Es gibt jedoch keine optionalen Felder und die normale Länge beträgt 20 Byte.

(4)Reserviert [6bit]

wird derzeit nicht verwendet, sein Wert ist 0

(5) Flag [6bit ]

Der TCP-Header enthält 6 Flag-Bits. Mehrere davon können gleichzeitig auf 1 gesetzt werden.

URG                                                                                          out out zusammen out out out out out out out Warten auf das Füllen des Puffers

RST bedeutet im Allgemeinen das Trennen einer Verbindung

Zum Beispiel: Ein TCP-Client initiiert eine Verbindung zu einem Server, der keinen Überwachungsport hat, und Wirshark erfasst das Paket wie folgt



Sie können diesen Host sehen: 192.168.63.134 initiiert eine Verbindungsanforderung an Host:192.168.63.132, aber Host:192.168.63.132 überwacht nicht auf der Serverseite den entsprechenden Port. Dies geschieht, wenn
Host: 192.168.63.132 ein TCP-Paket sendet, auf das RST eingestellt ist trennen.

SYN Die Synchronisationssequenznummer wird zum Initiieren einer Verbindung verwendet

FIN Der Absender schließt die Sendeaufgabe ab (d. h. trennt die Verbindung)

(6)Fenstergröße (Fenster) [16bit]

Die Größe des Fensters, die die maximale Anzahl von Bytes angibt, die die Quellmethode akzeptieren kann. .

(7) Prüfsumme [16bit]

Die Prüfsumme deckt das gesamte TCP-Nachrichtensegment ab: TCP-Header und TCP-Daten. Hierbei handelt es sich um ein Pflichtfeld, das vom Absender berechnet und gespeichert und vom Empfänger überprüft werden muss.

(8) Notfallzeiger [16bit]

Der Notfallzeiger ist nur gültig, wenn das URG-Flag auf 1 gesetzt ist. Der Dringlichkeitszeiger ist ein positiver Offset, der zum Wert im Sequenznummernfeld addiert wird, um die Sequenznummer des letzten Bytes dringender Daten darzustellen. Der Notfallmodus von TCP ist eine Möglichkeit für den Absender, dringende Daten an das andere Ende zu senden.

(9) TCP-Option

ist optional, wir werden sie uns später beim Erfassen von Paketen ansehen

2 . Wichtige Details

(1) Drei-Wege-Handshake zum Herstellen einer Verbindung

a. Das anfordernde Ende (normalerweise Client genannt) sendet ein SYN-Segment an Geben Sie den Client an. Den Port des Servers, zu dem Sie eine Verbindung herstellen möchten, sowie die anfängliche Sequenznummer (ISN, in diesem Fall 1415531521). Dieses SYN-Segment ist Nachrichtensegment 1.
b. Der Server sendet als Antwort ein SYN-Segment (Segment 2) zurück, das die ursprüngliche Sequenznummer des Servers enthält. Gleichzeitig wird die Bestätigungssequenznummer auf die ISN des Kunden plus 1 gesetzt, um das SYN-Nachrichtensegment des Kunden zu bestätigen. Ein SYN belegt eine Sequenznummer
c. Der Client muss die Bestätigungssequenznummer auf die ISN des Servers plus 1 setzen, um das SYN-Segment des Servers (Segment 3) zu bestätigen.
Diese drei Segmente vervollständigen den Verbindungsaufbau. Dieser Vorgang wird auch als Drei-Wege-Handshake bezeichnet


Verwenden Sie Wirshark, um Pakete wie folgt zu erfassen:


Sie können sehen, dass der Drei-Wege-Handshake die Sequenznummer der Pakete zwischen den beiden Parteien, die maximal empfangene Datengröße (Fenster) und die MSS (Maximum Segment Size) bestimmt.
MSS = MTU – IP-Header – MTU stellt die maximale Übertragungseinheit dar. Wir werden darüber sprechen, wenn wir den IP-Header analysieren. Sowohl der IP-Header als auch der TCP-Header umfassen 20 Bytes mit optionalen Optionen. In diesem Fall ist MSS=1500 - 20 -20 = 1460.

MSS begrenzt die Größe der von TCP-Paketen übertragenen Daten. Das bedeutet, dass, wenn die Anwendungsschicht Daten über das TCP-Protokoll an die Transportschicht übermittelt, dies der Fall sein muss segmentiert, in mehrere Segmente unterteilt und einzeln gesendet werden.

Beispiel: Die Anwendungsschicht übermittelt 4096 Byte Daten gleichzeitig an die Transportschicht. Zu diesem Zeitpunkt ist der Paketerfassungseffekt durch Wirshark wie folgt:


Die ersten drei Male sind der Drei-Wege-Handshake-Prozess, und die nächsten drei Male sind der Prozess der Datenübertragung. Da die Datengröße 4096 Bytes beträgt, dauert die Übertragung dreimal (1448). + 1448 + 1200). Aufmerksame Leute werden sich fragen, warum die maximale Datengröße, die jedes Mal übertragen wird, nicht 1460 Bytes beträgt, da TCP hier optionale Optionen enthält, TCP-Header-Länge = 20 + 12 (optionale Optionsgröße) = 32 Bytes. Die maximale Datenmenge, die auf diese Weise übertragen werden kann, beträgt: 1500 - 20 - 32 = 1448 Bytes.

(2) Winken Sie viermal, um die Verbindung zu trennen

a. Die aktuelle Netzwerkkommunikation basiert auf Sockets. Wenn der Client seinen eigenen Socket schließt, wird der Kernel-Protokollstapel automatisch geschlossen Senden Sie ein Paket mit festgelegter FIN an den Server und fordern Sie zum Trennen der Verbindung auf. Wir nennen den Teilnehmer, der zuerst die Sperranforderung initiiert, den aktiv trennenden Teilnehmer.
b. Nachdem der Server die FIN-Trennungsanforderung vom Client erhalten hat, sendet der Kernel-Protokollstapel sofort ein ACK-Paket als Antwort, das angibt, dass die Anforderung des Clients empfangen wurde.
c Für eine gewisse Zeit schaltet es den Socket selbst ab. Zu diesem Zeitpunkt sendet der Kernel-Protokollstapel ein FIN-Set-Paket an den Client mit der Aufforderung, die Verbindung zu trennen
d Nachdem der Client die FIN-Trennungsanforderung vom Server erhalten hat, sendet er als Antwort eine Bestätigung, die die Anforderung von angibt Der Server wurde empfangen


Verwenden Sie Wirshar, um das Paket zu erfassen und wie folgt zu analysieren:


(3) Garantie der TCP-Zuverlässigkeit

TCP verwendet eine Technologie namens „positive Bestätigung mit erneuter Übertragung“ als Grundlage für die Bereitstellung zuverlässiger Datenübertragungsdienste. Diese Technologie erfordert, dass der Empfänger nach dem Empfang der Daten Bestätigungsinformationen ACK an die Quellstation zurücksendet. Der Absender zeichnet jedes gesendete Paket auf und wartet auf die Bestätigung, bevor er das nächste Paket sendet. Der Absender startet beim Senden des Pakets außerdem einen Timer und sendet das gerade gesendete Paket erneut, wenn der Timer abgelaufen ist, die Bestätigungsinformationen jedoch nicht angekommen sind. Abbildung 3-5 zeigt die Datenübertragungssituation des positiven Bestätigungsprotokolls mit Neuübertragungsfunktion, und Abbildung 3-6 zeigt das durch Paketverlust verursachte Timeout und die Neuübertragung. Um verspätete Bestätigungen und doppelte Bestätigungen aufgrund von Netzwerkverzögerungen zu vermeiden, schreibt das Protokoll vor, dass die Bestätigungsinformationen eine Paketsequenznummer enthalten, damit der Empfänger das Paket korrekt der Bestätigung zuordnen kann.

Wie aus Abbildung 3-5 ersichtlich ist, kann das Netzwerk zwar gleichzeitig eine bidirektionale Kommunikation durchführen, da das Senden des nächsten Pakets verschoben werden muss, bevor die Bestätigungsinformationen des Netzwerks empfangen werden vorheriges Paket, das einfache positive Bestätigungsprotokoll Es wird viel wertvolle Netzwerkbandbreite verschwendet. Zu diesem Zweck verwendet TCP einen Schiebefenstermechanismus, um den Netzwerkdurchsatz zu verbessern und gleichzeitig eine durchgängige Flusskontrolle zu lösen.



(4) Schiebefenstertechnologie

Die Schiebefenstertechnologie ist ein einfacher positiver Bestätigungsmechanismus mit komplexerer Neuübertragung Variante, die es dem Absender ermöglicht, mehrere Pakete zu senden, bevor er auf eine Bestätigung wartet. Wie in Abbildung 3-7 dargestellt, möchte der Absender eine Paketsequenz senden. Das Sliding-Window-Protokoll fügt ein Fenster mit fester Länge in die Paketsequenz ein und sendet dann alle Pakete im Fenster, wenn ein Paket empfangen wird Wenn Bestätigungsinformationen empfangen werden, kann das Fenster zurückgeschoben und das nächste Paket gesendet werden.



2. UDP-Protokoll

UDP-Protokoll ist auch ein Transportschichtprotokoll , Transportschichtprotokolle, die keine Zuverlässigkeit garantieren. Der Protokollheader ist relativ einfach und lautet wie folgt:



Die Portnummer wird hier nicht erklärt, sie hat dieselbe Bedeutung wie die TCP-Portnummer.

Länge belegt 2 Bytes und identifiziert die Länge des UDP-Headers. Prüfsumme: Prüfsumme, einschließlich UDP-Header und Datenteile.

3. IP-Protokoll

IP ist das Kernprotokoll in der TCP/IP-Protokollfamilie. Alle TCP-, UDP-, ICMP- und IGMP-Daten werden im IP-Datagrammformat übertragen. Seine Eigenschaften sind wie folgt:
Unzuverlässig (u n r e l i a b l e) bedeutet, dass es nicht garantieren kann, dass das IP-Datagramm das Ziel erfolgreich erreichen kann. IP bietet nur die besten Übertragungsdienste. Wenn ein Fehler auftritt, beispielsweise wenn einem Router vorübergehend die Puffer ausgehen, verfügt IP über einen einfachen Fehlerbehandlungsalgorithmus: Verwerfen Sie das Datagramm und senden Sie dann eine ICMP-Nachricht an die Quelle. Die erforderliche Zuverlässigkeit muss von oberen Schichten (z. B. TCP) bereitgestellt werden.

Der Begriff verbindungslos bedeutet, dass IP keine Statusinformationen über nachfolgende Datagramme verwaltet. Jedes Datagramm wird unabhängig voneinander verarbeitet. Dies bedeutet auch, dass IP-Datagramme in der Reihenfolge empfangen werden können, in der sie gesendet wurden. Wenn eine Quelle zwei aufeinanderfolgende Datagramme (zuerst A, dann B) an dieselbe Senke sendet, wird jedes Datagramm unabhängig weitergeleitet und nimmt möglicherweise eine andere Route, sodass B möglicherweise vor A ankommt.

1. IP-Header-Format


(1) Die Version ist 4-stellig und bezieht sich auf die IP-Protokollversion. Die von beiden Kommunikationspartnern verwendeten IP-Protokollversionen müssen konsistent sein. Die derzeit weit verbreitete Versionsnummer des IP-Protokolls ist 4 (IPv4). Bezüglich IPv6 befindet es sich noch im Entwurfsstadium.

(2) Die Headerlänge beträgt 4 Ziffern und der maximal darstellbare Dezimalwert beträgt 15. Bitte beachten Sie, dass die Einheit der durch dieses Feld dargestellten Zahl eine 32-Bit-Wortlänge ist (eine 32-Bit-Wortlänge beträgt 4 Bytes). Die Länge erreicht 60 Byte. Wenn die Länge des IP-Paket-Headers kein ganzzahliges Vielfaches von 4 Byte ist, muss er mit dem letzten Füllfeld gefüllt werden. Daher beginnt der Datenteil immer bei einem ganzzahligen Vielfachen von 4 Bytes, was bei der Implementierung des IP-Protokolls praktischer ist. Der Nachteil der Begrenzung der Headerlänge auf 60 Byte besteht darin, dass sie in manchen Fällen möglicherweise nicht ausreicht. Dies geschieht jedoch in der Hoffnung, dass die Benutzer den Overhead minimieren. Die am häufigsten verwendete Header-Länge beträgt 20 Byte (dh die Header-Länge beträgt 0101), und derzeit werden keine Optionen verwendet.

(3) Differenzierte Dienste: 8 Bits werden verwendet, um bessere Dienste zu erhalten. Dieses Feld wurde im alten Standard als Servicetyp bezeichnet, wurde jedoch in der Praxis nie verwendet. 1998 benannte die IETF diesen Bereich in DS (Differentiated Services) um. Dieses Feld ist nur bei Verwendung differenzierter Dienste wirksam.

(4) Gesamtlänge Die Gesamtlänge bezieht sich auf die Länge des Headers und der Daten in Bytes. Das Gesamtlängenfeld beträgt 16 Bit, sodass die maximale Länge des Datagramms 216-1 = 65535 Byte beträgt.

Jede Datenverbindungsschicht unterhalb der IP-Schicht verfügt über ein eigenes Rahmenformat, das die maximale Länge des Datenfelds im Rahmenformat enthält, die als Maximum Transfer Unit (MTU) bezeichnet wird. Wenn ein Datagramm in einen Verbindungsschichtrahmen eingekapselt wird, darf die Gesamtlänge des Datagramms (d. h. der Header plus der Datenteil) den MTU-Wert der zugrunde liegenden Datenverbindungsschicht nicht überschreiten.

(5) Die Identifikation (Identifikation) umfasst 16 Ziffern. Die IP-Software verwaltet einen Zähler im Speicher. Bei jeder Generierung eines Datagramms wird der Zähler um 1 erhöht und dieser Wert dem Identifikationsfeld zugewiesen. Diese „Identifikation“ ist jedoch keine Sequenznummer, da IP ein verbindungsloser Dienst ist und es kein Problem gibt, Datagramme der Reihe nach zu empfangen. Wenn ein Datagramm fragmentiert werden muss, weil seine Länge die MTU des Netzwerks überschreitet, wird der Wert dieses Identifikationsfelds in das Identifikationsfeld aller Datagramme kopiert. Der gleiche Identifikationsfeldwert ermöglicht, dass jedes fragmentierte Datagrammfragment korrekt wieder zum ursprünglichen Datagramm zusammengesetzt wird.

(6) Flag (Flag) belegt 3 Ziffern, derzeit sind jedoch nur 2 Ziffern aussagekräftig.

●Das niedrigste Bit im Flag-Feld wird als MF (More Fragment) aufgezeichnet. MF=1 bedeutet, dass es später „fragmentierte“ Datagramme geben wird. MF=0 bedeutet, dass dies das letzte von mehreren Datagrammfragmenten ist

● Das Bit in der Mitte des Flag-Felds wird als DF (Don't Fragment) aufgezeichnet, was „kann nicht fragmentiert werden“ bedeutet. Fragmentierung ist nur zulässig, wenn DF=0.

(7) Der Slice-Offset belegt 13 Bit. Der Slice-Offset gibt an: die relative Position eines bestimmten Slice im Originalpaket nach der Fragmentierung eines längeren Pakets. Das heißt, dort, wo der Slice relativ zum Startpunkt des Benutzerdatenfelds beginnt. Der Slice-Offset wird in 8-Byte-Offset-Einheiten angegeben. Das bedeutet, dass die Länge jedes Fragments ein ganzzahliges Vielfaches von 8 Byte (64 Bit) sein muss.

(8) Time to Live belegt 8 Bit. Die häufig verwendete englische Abkürzung für das Time-to-Live-Feld ist TTL (Time To Live), was die Lebensdauer des Datagramms im Netzwerk angibt. Dieses Feld wird durch den Ursprung des Datagramms festgelegt. Sein Zweck besteht darin, zu verhindern, dass unzustellbare Datagramme auf unbestimmte Zeit im Internet zirkulieren und so Netzwerkressourcen vergeblich verbrauchen. Der ursprüngliche Entwurf sah vor, Sekunden als Einheit für TTL zu verwenden. Jedes Mal, wenn es einen Router durchläuft, wird die TTL von der Zeit abgezogen, die das Datagramm im Router benötigt. Wenn das Datagramm am Router weniger als 1 Sekunde dauert, wird der TTL-Wert um 1 dekrementiert. Wenn der TTL-Wert 0 ist, wird das Datagramm verworfen.

(9) Das Protokoll belegt 8 Bits. Das Protokollfeld gibt an, welches Protokoll für die in diesem Datagramm übertragenen Daten verwendet wird, sodass die IP-Schicht des Zielhosts weiß, an welchen Verarbeitungsprozess der Datenteil übergeben werden soll .

(10) Die erste Prüfsumme belegt 16 Stellen. Dieses Feld überprüft nur den Header des Datagramms, nicht jedoch den Datenteil. Dies liegt daran, dass der Router jedes Mal, wenn ein Datagramm einen Router durchläuft, die Header-Prüfsumme neu berechnen muss (einige Felder wie Lebensdauer, Flags, Fragment-Offsets usw. können sich ändern). Wenn Teile der Daten nicht überprüft werden, verringert sich der Rechenaufwand.

(11) Die Quell-IP-Adresse belegt 32 Bit.

(12) Die Ziel-IP-Adresse belegt 32 Bit.

2. Fragmentierungserklärung

Fragmentierung bedeutet, dass die zu übertragenden Daten größer als die maximale Übertragungseinheit (MTU) sind notwendig Teilen Sie es in mehrere Pakete auf und senden Sie diese einzeln an die andere Partei. Wenn wir über TCP und MSS sprechen, können viele Menschen sie nicht unterscheiden. Ich denke, wir können sie anhand des Bildes unten vollständig unterscheiden.

Ich persönlich bin der Meinung, dass bei der Übertragung von Daten über das TCP-Protokoll eine Fragmentierung definitiv nicht erforderlich ist, wenn sie die IP-Schicht erreichen. Eine Fragmentierung ist nur erforderlich, wenn große Datenmengen über das UDP-Protokoll übertragen werden.
Zum Beispiel: Verwenden Sie das UDP-Protokoll, um 10240 Byte Daten zu übertragen


Sie können es sehen, aber wenn die Daten an die Netzwerkschicht übermittelt werden, weil Die Daten überschreiten das Maximum. Die Übertragungseinheit ist fragmentiert. Teilen Sie es in mehrere Pakete auf und senden Sie diese über das IP-Protokoll an die andere Partei. Das maximale Byte jedes Pakets beträgt MTU – IP-Header = 1500 – 20 = 1480.

4. Ethernet-Header


Es besteht aus drei Teilen: Quell-MAC-Adresse | Ziel-MAC-Adresse |. Das verwendete Protokoll.

In Ethernet sind die Formate von Datenpaketen also wie folgt:


Das ARP-Protokoll erhält die entsprechende MAC-Adresse über die IP-Adresse, die als Address Resolution Protocol bezeichnet wird.

Das RARP-Protokoll erhält die entsprechende IP-Adresse über die MAC-Adresse, sogenanntes Reverse Address Resolution Protocol

Das obige ist der detaillierte Inhalt vonGrafische Einführung in die Protokolle TCP, UDP und IP in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn