WEBVTT

00:05.370 --> 00:12.990
Also, Leute, als nächstes werden wir die Implementierung von Unix-Domain-Sockets durchgehen, um unseren Server-Prozess zu implementieren.

00:13.950 --> 00:18.090
Als Erstes müssen wir also den Quellcode herunterladen.

00:18.900 --> 00:26.430
Stellen Sie also in Ihrem Linux-Terminal sicher, dass Sie mit dem Internet verbunden sind, und geben

00:26.430 --> 00:31.680
Sie zum Herunterladen des Quellcodes den Befehl git clone as Http.

00:33.780 --> 00:39.160
Gehen Sie zu github. com und dann CS-Praktika.

00:43.370 --> 00:46.630
Und Serverdesign.

00:46.640 --> 00:50.450
Beachten Sie also die Groß- und Kleinschreibung und drücken Sie einfach die Eingabetaste.

00:50.450 --> 00:54.680
Mit diesem Befehl können Sie den Ordner "Serverdesign" herunterladen.

00:55.790 --> 01:03.440
Gehen Sie nun in den Ordner, und hier sehen Sie ein Unix-Verzeichnis.

01:03.980 --> 01:07.840
In diesem Verzeichnis befinden sich also die C-Dateien der Clients und des Servers.

01:07.850 --> 01:14.210
Wir werden also die Datei server dot c besprechen, die den Server-Zustandsautomaten für Unix-Domain-Sockets

01:14.210 --> 01:16.160
implementiert.

01:17.000 --> 01:19.970
Also Leute, ich habe die Server-Dot-C-Datei geöffnet.

01:21.340 --> 01:27.610
Wir werden also die Implementierungsdetails der Unix-Domain-Socket-Implementierung eines Server-Prozesses

01:27.610 --> 01:28.420
durchgehen.

01:29.020 --> 01:31.960
Sie können also die Standard-Header-Dateien hier einbinden.

01:32.950 --> 01:35.950
Unix-Domain-Sockets haben also in der Regel einen Namen.

01:36.100 --> 01:44.860
Als Erstes müssen Sie also eine Konstante oder ein Makro erstellen, das sich zu einer Zeichenkette erweitert.

01:44.860 --> 01:51.490
Und diese Zeichenkette sollte innerhalb eines Systems so eindeutig sein, dass kein anderer Unix-Domain-Socket mit diesem Socket-Namen

01:51.520 --> 01:53.360
bereits geöffnet ist.

01:53.380 --> 01:59.320
Dies ist also der Socket-Name, den wir unserem Unix-Domain-Socket zuweisen werden, den wir erstellen

01:59.320 --> 02:00.460
werden.

02:01.340 --> 02:01.940
Richtig.

02:01.940 --> 02:09.230
Der nächste definierte Wert ist die Puffergröße, d.h. 128 Byte ist die Puffergröße,

02:09.230 --> 02:15.050
die unser Server verwenden wird, um Daten vom Client zu empfangen.

02:16.270 --> 02:22.990
Bevor ich also auf die Hauptfunktion eingehe, möchte ich Ihnen in groben Zügen erklären, wie

02:22.990 --> 02:26.290
unser Serverprozess genau funktioniert.

02:27.060 --> 02:30.630
Also Leute, lasst mich euch die Funktionsweise des Serverprozesses erklären.

02:30.630 --> 02:35.900
Das ist die eigentlich logische Funktionalität, die dieser Serverprozess implementiert.

02:35.910 --> 02:38.910
Wir haben also einen Serverprozess, richtig?

02:38.910 --> 02:40.290
Und nehmen wir an, es gibt einen Kunden.

02:40.320 --> 02:48.860
C1 Unser Serverprozess versteht also zunächst nur die Zahlenwerte, die vom Client gesendet werden.

02:48.870 --> 02:58.200
Angenommen, der Client sendet den Wert sechs, dann fügt der Serverprozess den Wert sechs zu seiner lokalen

02:58.200 --> 03:04.890
Variable result hinzu und addiert den Wert sechs zu diesem Ergebniswert.

03:04.920 --> 03:11.310
Nehmen wir nun an, der Client C1 sendet eine weitere Nachricht, sagen wir sieben, so dass der Serverprozess diese

03:11.310 --> 03:15.900
Zeile ausführt und das Ergebnis auf sechs plus sieben aktualisiert wird.

03:16.320 --> 03:16.980
Richtig.

03:16.980 --> 03:23.280
Und noch einmal: Wenn der Client-Prozess C1 den Wert acht sendet und anschließend den Wert acht, neun,

03:23.280 --> 03:29.950
zehn und so weiter, wird unser Server-Prozess weiterhin die vom Client gesendeten Werte hinzufügen.

03:31.480 --> 03:32.020
Richtig.

03:32.020 --> 03:35.470
Der Serverprozess antwortet also nicht mehr auf den Client.

03:35.470 --> 03:39.040
Es werden lediglich die vom Client gesendeten Werte übernommen.

03:39.070 --> 03:43.210
C1 Und sie berechnet die Summe dieser Werte.

03:43.630 --> 03:50.710
In dem Moment, in dem der Client einen speziellen Wert Null an den Server sendet, gibt der Server das Ergebnis

03:50.710 --> 03:53.150
zurück, das er bisher berechnet hat.

03:53.170 --> 03:58.600
Der Server-Prozess gibt also das Ergebnis zurück, das 40 beträgt.

03:58.720 --> 04:04.600
Dies ist also die einfache Funktionalität eines Serverprozesses, der die Summe aller ganzzahligen Werte

04:04.600 --> 04:07.900
berechnet, die vom Client C1 an den Server gesendet werden.

04:07.900 --> 04:14.620
Und in dem Moment, in dem der Client C1 den Wert Null an den Server sendet, bedeutet dies, dass der Client

04:14.620 --> 04:20.050
C1 nun den Server auffordert, das bisher berechnete Ergebnis zurückzusenden.

04:21.250 --> 04:23.920
Sobald der Server das Ergebnis an den Client zurückschickt.

04:24.460 --> 04:31.090
Der Server schließt dann die Verbindung mit dem Client C1 und ist nun bereit, den neuen Satz von Werten von

04:31.090 --> 04:33.640
einem neuen Client zu akzeptieren.

04:34.510 --> 04:40.960
Da Sie nun die Funktionsweise eines Serverprozesses kennen, wird es Ihnen leicht fallen, die Serverimplementierung

04:40.960 --> 04:43.960
oder den Servercode zu verstehen.

04:46.540 --> 04:52.060
Wir gehen also direkt in die Hauptfunktion hinein.

04:52.420 --> 04:59.730
Das erste, was Sie tun müssen, ist die Struktur zu nehmen, die von einem Standard-C-APIs und diese Struktur

04:59.740 --> 05:08.170
ist struct sockaddr underscore u n, und die Variable dieser Struktur Typ ist Name bereitgestellt wird.

05:08.290 --> 05:14.740
Wie wir also wissen, werden Unix-Domain-Sockets tatsächlich eindeutig durch einen Namen identifiziert.

05:15.400 --> 05:22.240
Um also den Namen der Unix-Domain-Sockets zu speichern, müssen Sie eine Variable dieses Strukturtyps definieren.

05:22.570 --> 05:25.120
Hier ist also die Definition dieser Struktur.

05:25.510 --> 05:28.400
Sie sehen also, dass diese Struktur zwei Mitglieder hat.

05:28.420 --> 05:35.560
Das erste Mitglied definiert die Adressfamilie Adressfamilie bedeutet, weil Sie die Unix-Domain-Sockets verwenden.

05:35.560 --> 05:41.350
Daher wird der Wert des ersten Mitglieds, das Sun family ist, immer ein konstanter Wert sein, der in

05:41.350 --> 05:44.170
den C-Standardbibliotheken definiert ist.

05:44.590 --> 05:52.760
Und dieser Wert ist ein F-Unterstrich Unix und Sie müssen diesen Wert verwenden, um Unix-Domain-Sockets zu erstellen.

05:52.880 --> 05:59.030
Und das zweite Mitglied ist eigentlich der Name des Unix-Domain-Sockets, richtig?

05:59.270 --> 06:03.830
Wir haben also einige lokale Variablen übernommen.

06:03.830 --> 06:09.770
Wir werden die Verwendung dieser lokalen Variablen im weiteren Verlauf der Diskussion unseres Codes erörtern.

06:12.350 --> 06:16.610
Hier können Sie sehen, dass wir einen lokalen Speicher namens Buffer genommen haben.

06:16.700 --> 06:23.510
Dieser Puffer wird vom Serverprozess verwendet, um die vom Client gesendeten Daten zu empfangen, und

06:23.510 --> 06:30.440
er wird vom Serverprozess verwendet, um das Ergebnis nach der Berechnung der Ergebnisse an den Client zu

06:30.440 --> 06:31.250
senden.

06:32.510 --> 06:40.010
In Zeile 34 sehen Sie, dass Sie den Unix-Domain-Socket zerstören, wenn er bereits unter diesem

06:40.010 --> 06:49.400
Namen erstellt wurde, denn Sie können nicht zwei Unix-Domain-Sockets mit demselben Namen erstellen.

06:49.760 --> 06:55.760
Es könnte also sein, dass Sie bereits ein Unix-Domain-Socket-Programm auf demselben Rechner in einem anderen

06:55.760 --> 06:57.020
Fenster ausführen.

06:57.020 --> 07:07.100
Und wenn dieser Unix-Domain-Socket zufällig den gleichen Namen hat, dann wird dieser Server, wenn Sie diese bestimmte Instanz

07:07.100 --> 07:13.530
des Server-Prozesses ausführen, diesen bestimmten Unix-Domain-Socket, der bereits

07:13.530 --> 07:19.980
von einem anderen Programm im System erstellt wurde, tatsächlich zerstören und einen

07:20.370 --> 07:25.740
Unix-Domain-Socket mit diesem Namen neu erstellen.

07:25.740 --> 07:30.450
Und dieses Programm wird den Besitz dieses Unix-Domain-Sockets übernehmen.

07:30.450 --> 07:37.590
Zeile 34 ist also eine Vorsichtsmaßnahme, damit Sie nicht zwei Unix-Domain-Sockets mit demselben Namen auf demselben Rechner ausführen

07:37.590 --> 07:39.450
oder versuchen zu erstellen.

07:39.780 --> 07:47.160
Gerade jetzt, wie wir wissen, dass der erste Schritt der Erstellung eines Unix-Domain-Server-Prozesses ist es, einen Master-Socket-Datei-Deskriptor

07:47.160 --> 07:51.900
oder die wir auch als Verbindung Socket erstellen.

07:51.900 --> 07:57.840
Wie Sie in diesem Flussdiagramm sehen können, besteht der erste Schritt des Serverprozesses darin, einen Socket zu erstellen.

07:58.080 --> 08:04.410
In Zeile 39 können Sie sehen, dass wir einen Master-Socket-Dateideskriptor erstellt haben, den wir auch als

08:04.410 --> 08:06.630
Verbindungs-Socket bezeichnen.

08:06.960 --> 08:11.910
Und das erste Argument des Socket-Systemaufrufs ist der Typ des Sockets, den Sie erstellen.

08:11.910 --> 08:16.740
In diesem Fall ist es also immer ein f Unterstrich Unix, richtig?

08:16.860 --> 08:22.710
Das zweite Argument legt fest, ob es sich bei dem Socket oder der Art der Kommunikation, die Ihr Serverprozess mit dem

08:22.710 --> 08:28.890
Client durchführt, um eine Stream-basierte Kommunikation oder eine Datagramm-basierte Kommunikation handelt.

08:29.070 --> 08:31.620
Also hier, um zu.

08:32.820 --> 08:37.770
Erstellen Sie eine Stream-basierte Kommunikation, müssen Sie den konstanten Wert übergeben, die sock underscore

08:37.830 --> 08:38.490
stream ist.

08:38.670 --> 08:46.230
Wenn Sie einen Server implementieren wollten, der auf Datagrammen basiert, dann hätten Sie sock underscore d

08:46.230 --> 08:51.630
gram flag als zweites Argument an den Socket-Systemaufruf übergeben müssen.

08:52.760 --> 08:57.620
Dann ist das dritte Argument nicht erforderlich und für diesen Kurs nicht diskussionswürdig.

08:57.620 --> 09:01.340
Das dritte Argument können Sie also immer als Null oder Null übergeben.

09:02.150 --> 09:07.040
Wenn also der Socket-Systemaufruf fehlschlägt, dann gibt er minus eins zurück.

09:07.310 --> 09:09.620
Dies ist also der Code für die Fehlerbehandlung.

09:11.240 --> 09:16.940
In Zeile 46 sind wir also in der Lage, einen Master-Socket-Dateideskriptor zu erstellen.

09:17.900 --> 09:18.740
Richtig.

09:18.980 --> 09:25.130
Der nächste Schritt, den der Serverprozess ausführt, ist also die Bindung.

09:25.580 --> 09:27.740
Was bewirkt nun der Systemaufruf bind?

09:30.140 --> 09:35.000
Bereiten wir uns also zunächst darauf vor, einen bind-Systemaufruf zu tätigen.

09:35.480 --> 09:39.230
Dann werde ich erklären, was die Funktionalität von bind system call ist?

09:39.980 --> 09:46.520
Erinnern Sie sich also daran, dass der Name die Variable vom Datentyp struct sockaddr underscore un war.

09:47.060 --> 09:50.630
Wir initialisieren hier also nur die Namensvariable.

09:50.900 --> 09:55.670
Und diese Struktur hatte, wie ich bereits erklärt habe, zwei Mitglieder.

09:55.700 --> 09:57.210
Die erste ist die Familie.

09:57.230 --> 10:00.350
Familienwert ist also immer ein f Unterstrich Unix.

10:00.530 --> 10:03.830
Das zweite Element ist der Name des Sockets.

10:03.860 --> 10:11.100
Mit STR und CP kopieren wir also den Namen des Sockets in diese Struktur.

10:11.890 --> 10:12.490
Richtig.
