Hinweis: Es ist ein persönliches Memo. Wir übernehmen keine Garantie für die Richtigkeit des Inhalts. Wenn Sie keine Kenntnisse über das Verwendungssystem oder die C-Sprache haben, ahmen Sie diese bitte nicht nach. es ist gefährlich. (Während der Bearbeitung)
Die Kommunikation zwischen Prozessen kann auf demselben Computer wie einer Pipe (Pipe (2)) oder einem FIFO (Named Pipe) durchgeführt werden. Grundsätzlich erfolgt diese prozessübergreifende Kommunikation auf einem anderen Computer in einem Netzwerk, zu dem Sie nicht gehören. Es bedeutet, was gemäß der Kommunikationsvereinbarung getan wird.
Strukturausrichtung, Bytereihenfolge und wie der Adressbus auf eine Adresse zeigt Die Busbreite usw. unterscheiden sich je nach verwendeter Architektur. C-Sprache beauftragt C-Sprachbenutzer, den Unterschied zu erkennen. Verlassen Sie sich bei der Kommunikation mit verschiedenen Computern im Netzwerk nicht auf den Computer. Beispielsweise kann bei einem RISC-Prozessor der Zugriff auf eine ungerade Adresse zu einem Busfehler führen.
Die Netzwerkprogrammierung verwendet Systemaufrufe (uapi), um Anwendungen zu erstellen. In Benutzeranwendungen arbeitet der Kernel im Benutzermodus und verwendet virtuellen Speicher. Das Betriebssystem verwaltet die Netzwerkmodule direkt. Dies erfolgt im Kernel-Modus (privilegierter Modus).
Netzwerkanwendungen verwenden eine Schnittstelle namens Sockets. Sockets können als spezielle Dateien behandelt werden. Setzen Sie sokect (2) ab, um einen Socket zu erstellen.
Sockets sind noch Dateien. Daher können auch binäre Ein- / Ausgabefunktionen wie Lesen (2) und Schreiben (2) verwendet werden.
Der erstellte Socket kann mit bind (2) adressiert werden. Da Sockets ein Dateityp sind, werden sie auch von der Inode-Nummer verwaltet.
Das Netzwerkmodul, das den Socket enthält, verfügt über einen Puffer zum Speichern der Daten Stellt das Paket in die Warteschlange. So fordern Sie das Betriebssystem auf, Daten zu senden Geben Sie send (2) in der sendenden Anwendung aus. (Es ist eine Anfrage, keine Garantie) Wenn im Puffer freier Speicherplatz vorhanden ist, wird dieser in der Warteschlange gespeichert.
Daten können durch Ausgabe von recv (2) in der empfangenden Anwendung erhalten werden. Datenabruf aus dem Puffer anfordern. Das Programm wird blockiert, wenn die empfangenen Daten nicht in der Warteschlange vorhanden sind. Beachten Sie, dass recv (2) Daten aus dem Puffer abruft, auch wenn die Anwendung nicht ausgeführt wird. Beachten Sie, dass Daten auf unbestimmte Zeit abgerufen werden, wenn sie nicht normal enden.
Unterbrechungen werden von der Netzwerkkarte zum Senden und Empfangen von Daten verwendet. Dies wird vom Kernel erledigt, In der Sprache C wird ein abstrahiertes Signal für den Benutzer vorbereitet.
Wenn Anforderungen von mehreren Clients an eine Netzwerkanwendung vorliegen Die Anwendung kann die Verarbeitungsleistung überschreiten. In diesem Fall werden Multi-Process, Multi-Thread, Select (2) usw. verwendet.
Mit connect (2) wird der Kommunikationspartner auf Anwendungsebene identifiziert. Wenn der Datenübertragungs- / Empfangsprozess während des Verbindungsaufbaus nicht normal abgeschlossen ist, unabhängig davon, ob es sich um TCP oder UDP handelt. Wenn sie nicht berührt werden, kann die Verarbeitung für immer blockiert werden. Wenn es schlecht ist, wird auch die Tasteneingabe nicht akzeptiert.
Daher tritt eine Zeitüberschreitung in alerm (2), setitimer (2) usw. auf. Angemessene Signalverarbeitung mit Sigaktion (2) usw.
Viele Protokolle werden durch C-Sprachstrukturen dargestellt. Viele dieser Details finden Sie in den folgenden Verzeichnissen:
/usr/include/net/* /usr/include/netinet/*
TCP/IP
In TCP / IP erfolgt die Kommunikation durch Paketaustausch.
Ein Paket besteht aus einem Header und einer Nutzlast.
Der Header enthält Informationen zur Zieladresse, Quelladresse, Nutzlast usw.
Die Nutzlast sind die Daten selbst, mit denen Sie kommunizieren möchten
Auf dem Betriebssystem wird eine Kommunikationsanwendung erstellt, und die zwischen diesen Anwendungen ausgetauschten Daten werden als Nachricht bezeichnet.
Die Datentypen in den unten aufgeführten Headern garantieren die Größe in Bit. Dies ist auch für POSIX-kompatible Betriebssysteme vorgesehen.
/usr/include/stdint.h
<stdint.h> <inttypes.h> (C99)
Beispiel:
uint32_t /*32-Bit-Int-Typ ohne Vorzeichen*/
Wie es definiert ist, hängt vom System ab. Weitere Informationen finden Sie direkt in der Kopfzeile.
TCP / IP-Protokoll Protokoll-Header im Netzwerk Vereinheitlichen Sie Anwendungsnachrichten mit Big Endians. Die folgenden Funktionen können für die Endian-Konvertierung verwendet werden.
#include <arpa/inet.h> /*Je nach System<net/inet.h> */
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
#include <stdio.h>
#include <arpa/inet.h>
int main(void)
{
uint32_t s = 0xff;
/* host to network endian */
uint32_t r = htonl(s);
printf("%#0.8x\n", r);
printf("%#0.8x\n", s);
return 0;
}
Ergebnisbeispiel
0xff000000
0x000000ff
1 . Verwenden Sie die Datei / etc / hosts
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
#include <sys/socket.h>
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);
2 . Verwenden Sie DNS
#include <sys/socket.h>
void sethostent(int stayopen);
void endhostent(void);
Wenn Sie den Namen beim DNS-Server auflösen, registrieren Sie die Adresse vorab beim DNS-Server in /etc/resolv.conf.
/etc/protocols
#include <netdb.h>
struct protoent *getprotoent(void);
struct protoent *getprotobyname(const char *name);
struct protoent *getprotobynumber(int proto);
/etc/services
#include <netdb.h>
struct servent *getservent(void);
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
Recommended Posts