Super detaillierte Erläuterung der Grundkenntnisse der C/C++-Netzwerkprogrammierung Teil 1 (systematischer Lerntag 11)

Inhaltsverzeichnis

Vorwort

1. Die Bedeutung und Zusammensetzung des Netzwerks

Bedeutung:

Komposition: 

2. Netzwerkarchitektur

1>OSI-Siebenschichtmodell

2>TCP/IP-Protokollarchitektur 

3>Wie werden Daten gekapselt, nachdem sie die Architektur durchlaufen haben? 

4>Portnummer

5>Big-Endian-Reihenfolge

6>TCP/UDP-Transportschichtprotokoll 

3. Systemfunktions-API-Lernframework (TCP)    

Server (Priorität):

 Klient:

4. Beispiele für Server- und Client-Code 

Zusammenfassen


Vorwort

Unter Netzwerkprogrammierung versteht man den Prozess der Verwendung von Programmiersprachen für die Netzwerkkommunikation. Durch Netzwerkprogrammierung können Computer über das Internet oder ein lokales Netzwerk Daten austauschen und mit anderen Computern kommunizieren. Bei der Netzwerkprogrammierung müssen Programmierer bestimmte Netzwerkprogrammierschnittstellen und -protokolle (z. B. TCP/IP, HTTP usw.) verwenden, um Daten zu senden und zu empfangen. Netzwerkprogrammierung wird häufig zur Entwicklung von Netzwerkanwendungen, Remote-Diensten, verteilten Systemen usw. verwendet.

Die Netzwerkprogrammierung hat folgende wichtige Funktionen:

  1. Datenaustausch und Kommunikation: Durch Netzwerkprogrammierung können Computer Daten im Netzwerk senden und empfangen, um Informationsaustausch und Kommunikation zu erreichen. Dies ist sehr wichtig für die Implementierung von Remote-Diensten, verteilten Systemen und Netzwerkanwendungen.

  2. Verteiltes System: Durch Netzwerkprogrammierung können mehrere Computer zu einem verteilten System verbunden werden. In einem verteilten System können verschiedene Computer miteinander kommunizieren und zusammenarbeiten, Ressourcen gemeinsam nutzen und Aufgaben bearbeiten und so die Zuverlässigkeit, Leistung und Skalierbarkeit des Systems verbessern.

  3. Entwicklung von Netzwerkanwendungen: Die Netzwerkprogrammierung ist die Grundlage für die Entwicklung von Netzwerkanwendungen (z. B. Webanwendungen, Chatrooms, Online-Spiele usw.). Durch Netzwerkprogrammierung kann eine Dateninteraktion zwischen dem Server und dem Client realisiert werden, wodurch die Interaktion zwischen dem Benutzer und dem Server sowie die Anzeige von Informationen realisiert werden.

  4. Netzwerksicherheit: Die Netzwerkprogrammierung ist auch eng mit der Netzwerksicherheit verbunden. Durch Netzwerkprogrammierung können Sicherheitsmechanismen wie Verschlüsselung, Authentifizierung und die Verhinderung von Informationslecks implementiert werden, um die Privatsphäre und Sicherheit der Netzwerkkommunikation zu schützen.

Kurz gesagt, die Netzwerkprogrammierung stellt eine technische Grundlage für den Datenaustausch und die Kommunikation zwischen Computern dar und ist zu einem wichtigen Mittel zum Aufbau verteilter Systeme, zur Entwicklung von Netzwerkanwendungen und zur Gewährleistung der Netzwerksicherheit geworden.


1. Die Bedeutung und Zusammensetzung des Netzwerks

Bedeutung:

   1. Was ist ein Netzwerk?
        Das Netzwerk ist eine virtuelle Welt zum Senden, Empfangen und Teilen von Informationen. Durch das Sammeln aller
Informationen im globales Dorf, Dies ermöglicht die gemeinsame Nutzung dieser Ressourcen.
        Ursprüngliche Absicht: Wissensaustausch            

bilden: 

 2. Woraus besteht das Software-Level-Netzwerk auf dem Computer?
        1>IP
            Format:
                Dotted Decimal Benutzer-Browsing und -Schreiben 192.168.10.x
                Netzwerk-Binärkombination 0,1, die vom System und Computer gesehen wird
            Kategorie:                     Gepunktete Dezimalzahl 4 Bytes                     Netzwerkbinärzahl 32 Bits                 (42 IP-Adressen)                 IPv6 (Mobiltelefon-WLAN, derzeit nicht im Computer konzentriert) Dimoticon 16. Bytes                     Netzwerk binär 128 Bit







                zu  

                 

                 

(1) Klasse-A-Adresse
                    Netzwerkbinär: beginnt mit 0
                    1 Netzwerkadresse 3 Hostadressen (die Netzwerkadresse ist gleich der Eins Sie befinden sich in welchem ​​Klassenzimmer, die Hostadresse
                    stellt Ihren Standort im Klassenzimmer dar)
Netzwerkbinärdatei:
00000000 00000000 00000000 00000001 - 01111111 11111111 11111111 11111110 
Gepunktete Dezimalzahl:
    0.0.0.1-127.255.255.254  
Hinweis:
        Die Host-Bits sind alle 0, definiert als Netzwerksegmentnummer, Netzwerk-ID-Nummer
        Die Host-Bits sind alle 1, definiert als Broadcast-Adresse
        

(2) Klasse-B-Adresse
                    Netzwerkbinär: beginnt mit 10
                    2 Netzwerkadressen und 2 Hostadressen (die Netzwerkadresse ist gleich der (eines, in dem Sie sich befinden. Welches Klassenzimmer, Host-Adresse
                    stellt Ihren Standort im Klassenzimmer dar)
Netzwerkbinärdatei:
10000000 00000000 00000000 00000001 - 10111111 11111111 11111111 11111110 
Gepunktete Dezimalzahl:
    128.0.0.1-191.255.255.254  
Hinweis:
        Die Host-Bits sind alle 0, definiert als Netzwerksegmentnummer, Netzwerk-ID-Nummer
        Die Host-Bits sind alle 1, definiert als Broadcast-Adresse

(3) Klasse-C-Adresse
                    Netzwerkbinär: beginnt mit 110
                    3 Netzwerkadressen und 1 Hostadresse (die Netzwerkadresse ist gleich (eines, in dem Sie sich befinden. Welches Klassenzimmer, Host-Adresse
                    stellt Ihren Standort im Klassenzimmer dar)
Netzwerkbinärdatei:
11000000 00000000 00000000 00000001 - 11011111 11111111 11111111 11111110 
Gepunktete Dezimalzahl:
    192.0.0.1-223.255.255.254  
Hinweis:
        Die Host-Bits sind alle 0, definiert als Netzwerksegmentnummer, Netzwerk-ID-Nummer
        Die Host-Bits sind alle 1, definiert als Broadcast-Adresse

(4) Klasse-D-Adresse
                    Netzwerkbinär: beginnt mit 1110
                    4 Netzwerkadressen 0 Hostadressen (die Netzwerkadresse ist gleich der Eins Sie befinden sich in welchem ​​Klassenzimmer, die Hostadresse
                    stellt Ihren Standort im Klassenzimmer dar)
Netzwerkbinärdatei:
11100000 00000000 00000000 00000001 - 11101111 11111111 11111111 11111110 
Gepunktete Dezimalzahl:
    224.0.0.1-239.255.255.254    
Hinweis:
        Die Host-Bits sind alle 0, was als Netzwerksegmentnummer und Netzwerk-ID-Nummer definiert ist
        Die Host-Bits sind alle 1, was die Broadcast-Adresse definiert            
        
(5) Adresse der Klasse E< /span>
                    Die Zukunft ist vielversprechend

        2>Subnetzmaske
            Netzwerkadresse ist alles 1, Host ist alles 0
            255.255.255.0
            Wird verwendet um festzustellen, ob sie sich im selben Netzwerksegment befinden
            Präfixlänge: 24 (hängt hauptsächlich von der Anzahl der Einsen in der Subnetzmaske ab)
            --> In Linux Dies spiegelt sich in der Netzwerkkonfiguration wider
            
        3>Standard-Gateway
            Der Standardwert der Hostadresse ist 1, wählen Sie zufällig 1-254 aus und entfernen Sie den Anfang und Schwanz
            Wird verwendet, um die Informationsübertragung im aktuellen Netzwerksegment zu verwalten; Netzwerkportal
            -->Kombiniertes Bildverständnis
            
        4> ;DNS-Domänennamenauflösungsserver a>
            Basierend auf dem vom lokalen Betreiber bereitgestellten DNS-Domänennamenserver
            202.98.128.86
            www.baidu.com
            IP-Standort: Guangdong, Shenzhen

2. Netzwerkarchitektur

1.OSI-Siebenschichtmodell

 Netzwerksystemmodell, das von einem ISO-Unternehmen eingeführt wurde
        
        Protokoll: Von beiden Parteien festgelegte Kommunikationsregeln
            Anwendungsschicht
            Darstellung Layer
            using using using using using   out out out out out out of ' s           through ' through ' ' s ' ' ‐ ‐ ‐ ‐ ‐ ‐ n und 8> Physikalische Schicht         Zweck: Daten kapseln und ein vereinbartes Kommunikationsprotokoll bilden         Nachteile: zu komplex, zu umständlich und schwer zu schreiben. Funktionsduplizierung




        

2.TCP/IP-Protokollarchitektur 

        Anwendungsschicht FTP, http, Ping, SSH        
        Transportschicht TCP, UDP
        Netzwerkschicht IP, ICMP, IGMP
        Physische Schicht Netzwerkkabel
        
        Konzentrieren Sie sich auf das Erlernen der Netzwerkarchitektur und der Welt der Netzwerkprotokolle

3. Wie werden Daten gekapselt, nachdem sie die Systemstruktur durchlaufen haben? 

 Der Zweck der Kapselung von Daten besteht darin, die Stabilität der Datenübertragung im Netzwerk sicherzustellen
            ·

4.Portnummer

 Unterscheiden Sie zwischen verschiedenen Anwendungen für den Host
            QQ4999, WeChat 5050
            2 Bytes 0~65535
            0 ~1023 --》Wird von Systemprozessen verwendet
            1024~65535 --》Wird von Benutzern verwendet 

5. Big- und Small-Endian-Reihenfolge

 Bei Hosts mit unterschiedlichen CPU-Typen gibt es zwei Arten der Ganzzahl-Byte-Reihenfolge für die Speicherspeicherung.
            Little-Endian-Reihenfolge:
                Die untere Reihenfolge Byte wird in der niedrigen Adresse gespeichert, Linux
            Big Endian: 
                Das niedrige Byte wird in der hohen Adresse gespeichert, System

6.TCP/UDP-Transportschichtprotokoll 

    Der Unterschied zwischen TCP/UDP:
        Eigenschaften von UDP (User Datagram Protocol): Nur Senden, keine Verbindungsattribute, daher sind die Daten unzuverlässig, instabil und können leicht verloren gehen.
        vertrauenswürdig.                                                                                                                               . . .         Beispiel: Bringen Sie ein Telefon mit
        

3. Systemfunktions-API-Lernframework (TCP)    

Server (Priorität):

     Frame:             
                1>Socket erstellen
                2>Eigene IP-Adresse und Portnummer binden
                3> ;Abhören
                4>Warten auf Client-Verbindung
                5>Daten empfangen/empfangen
                6 >Socket schließen (Dateideskriptor mit Netzwerkattribute) 

1.创gebauter Socket套字 (Socket)

   Kopfdatei:

    #include<sys/types.h>
    #include<sys/socket.h>
    int socket(int domain, int type, int Protokoll);
    Funktion:
        Erstellen Sie einen Dateideskriptor mit Netzwerkattributen
    Parameter:
        domain:Protokollfamilie
            AF_UNIX,AF_LOCAL Lokale Verbindung
            AF_INET IPv4
            AF_INET6 IPv6
        Typ:
        SOCK_STREAM Streaming-Socket TCP
        SOCK_DGRAM Datagramm-Socket UDP
        SOCK_RAW Raw-Socket
        Protokoll :
            Der Standardwert ist 0, was bedeutet, dass die ersten beiden ausgewählten Parameter wirksam sind.
    Rückgabewert:
        Gibt erfolgreich einen Dateideskriptor zurück mit Netzwerkattributen
        Fehler, gibt -1 zurück und setzt den Fehlercode
        
    Wo befindet sich der Socket? Zwischen der Anwendungsschicht und dem Transportschichtraum

 2. Binden Sie Ihre eigene IP-Adresse und Portnummer (bind)

    Kopfdatei:

    #include<sys/types.h>
    #include<sys/socket.h>
    int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
    Funktion:
        IP-Adresse und Portnummer an sockfd binden. Die Schwierigkeit liegt in der Zuweisung der zweiten Parameterstruktur             char sa_data[14]; 14 Bytes        sa_family_t sa_family; 2 Bytes     struct sockaddr {     Zweiter Parameter const struct sockaddr *my_addr         Fehler, Rückgabe -1 und Fehlercode festlegen         Gibt erfolgreich 0 zurück     Rückgabewert:         addrlen: Länge der Struktur         my_addr: Strukturzeiger, der für die Zuweisung von IP-Adressen verwendet wird und Portnummer         sockfd: Dies ist ein Dateideskriptor mit Netzwerkattributen, der von Socket erstellt wird
    Parameter:         Beim Zuweisen von Werten ist nicht sicher, welcher zuerst kommt, die IP-Adresse und die Portnummer.         Die IP-Adresse und die Portnummer belegen nur 6 Bytes. , wie man die restlichen 8 Bytes füllt     Verwenden Sie daher die gleiche Familienstruktur     struct sockaddr_in{         sa_family_t sin_family; //Adressfamilie         uint16_t sin_port; //Portnummer          struct in_addr sin_addr; //32-bit IP-Adresse         char sin_zero[8]; //Reserviert und unbenutzt, automatisch mit 0 gefüllt     };     struct in_addr{         In_addr_t s_addr; //32-Bit-IPv4-Adresse     };






    

    




    



        









    1>Achten Sie auf das Problem der Port-Endian-Konvertierung
    #include <arpa/inet.h>
    
    uint32_t htonl(uint32_t hostlong) ; 32 Bit
    uint16_t htons(uint16_t hostshort); 16 Bit
    Wandeln Sie die obige Little-Endian-Reihenfolge in eine Big-Endian-Reihenfolge um
    
    uint32_t ntohl(uint32_t netlong);
    uint16_t ntohs(uint16_t netshort);
    Big-Endian-Reihenfolge zurück in Little-Endian-Reihenfolge umwandeln

    2>Auf IP-Formatkonvertierung achten
    #include <netinet/in.h>
    in_addr_t inet_addr(const char *cp);     Konvertieren Sie die Netzwerk-Binärzahl zurück in eine Punkt-Dezimalzahl     char *inet_ntoa(struct in_addr in);
    Konvertieren Sie die IP-Adresse mit Punkt-Dezimalzahl in eine Netzwerk-Binärzahl.
    

3.监听 (zuhören)

    Header-Datei:
    #include <sys/types.h>
    #include <sys/socket.h>
    int listen(int sockfd, int backlog);
    Funktion:
        Schützen Sie den Server und begrenzen Sie die maximale Anzahl gleichzeitiger Clientverbindungen         Fehler, gibt -1 zurück und legt den Fehlercode fest         Erfolg gibt 0 zurück     Rückgabewert:         backlog: die maximale Anzahl von Client-Verbindungen         sockfd: Dies ist ein Dateideskriptor mit Netzwerkattributen, der vom Socket erstellt wird
    Parameter:




4. Warten auf Client-Verbindung (Warten bedeutet „Blockieren“ akzeptieren)

   Kopfdatei:

    #include <sys/types.h>
    #include <sys/socket.h>
    int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    Funktion:
        Beim Warten auf die Clientverbindung kann der zweite Parameter die IP-Adresse und Portnummer der anderen Partei speichern, ohne dass dies erforderlich ist Zum Speichern setzt die andere Partei NULL
    Parameter:
        sockfd: Dies ist ein Dateideskriptor mit Netzwerkattributen, der vom Socket erstellt wird
        addr: Verwenden Sie eine Struktur, um Clientinformationen zu speichern
        addrlen: die Länge der Struktur.
    Rückgabewert:
        Gibt den Dateideskriptor für die Kommunikation mit dem Client erfolgreich zurück, ähnlich der Socket-Funktion.
        Fehler, gibt zurück – 1 und stellen Sie den Fehlercode ein

 Klient:

Um den offensichtlichen Effekt zu demonstrieren, haben wir mit dem Schreiben des Client-Frameworks begonnen

        1>Socket erstellen
        2>IP-Adresse und Portnummer des Servers angeben
        3>Aktive Verbindung zum Server herstellen         5>Dateideskriptor schließen
        4>Daten empfangen/empfangen

1. Erstellen Sie einen Socket ähnlich dem Server

2. Geben Sie die IP-Adresse und Portnummer des Servers an

        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port = htons(8888);
        server.sin_addr.s_addr = inet_addr("192.168.10.5");
        Beachten Sie, dass die Anweisung anderen gehört und nichts mit Ihnen zu tun hat

3. Hauptbetriebsdienstausrüstung (anschließen)

    Kopfdatei:

    #include <sys/types.h>
    #include <sys/socket.h>
    int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen)
    Funktion:
        Aktive Verbindung zum Server herstellen. Der zweite Parameter kann die IP-Adresse und Portnummer der anderen Partei speichern. Keine Notwendigkeit um NULL zu setzen< /span>         Fehler, gibt -1 zurück und legt den Fehlercode fest         Erfolg gibt 0 zurück     Rückgabewert:         addrlen: Die Länge der Struktur, im Allgemeinen sizeof() verwenden.         addr: wird zum Herstellen einer Verbindung verwendet zur Serverstruktur         sockfd: Dies ist ein Dateideskriptor mit Netzwerkattributen, der von socket erstellt wird
    Parameter:





 4. Nummer senden (senden)

    Kopfdatei:

    #include <sys/types.h>
    #include <sys/socket.h>
 
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    Funktion:
        Datenversand
    Parameter:
        sockfd: Socket-Dateideskriptor
        buf: Sendepuffer
        len: Sendepufferlänge
        Flags: Standard ist 0, zeigt Blockierung an
    Rückgabewert:
    Erfolg: Gibt die Anzahl der gesendeten Bytes zurück
    Fehler: Gibt -1 zurück und setzt errno< /span>

 5.Anzahl der Verbindungen (recv)

   Kopfdatei:

    #include <sys/types.h>
    #include <sys/socket.h>
    ssize_t recv(int sockfd,void *buf, size_t len, int flags);
    Funktion:
        Datenempfang
    Parameter:
        sockfd: Socket-Dateideskriptor
        buf: Empfangspuffer
        len: Empfangspufferlänge
        Flags: Der Standardwert ist 0, Zeigt Blockierung an
    Rückgabewert:
    >0: Gibt die Anzahl der empfangenen Bytes zurück
    =0: Client Das Terminal wurde abnormal beendet (STRG+C)
    <0: Fehler: Geben Sie -1 zurück und setzen Sie die Fehlernummer 

4. Beispiele für Server- und Client-Code 

//服务器代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>

int main(void)
{
	//1>创建socket套接字
	int serfd = socket(AF_INET,SOCK_STREAM,0);//1.选IPv4,2选TCP,3默认0
	if(serfd<0)	//错误判断
	{
		perror("socket");
		return -1;
	}
	printf("创建出的socket的值为%d\n",serfd);
	//2>绑定自己的IP地址和端口号
	struct sockaddr_in my_addr;
	my_addr.sin_family = AF_INET;//IPv4
	my_addr.sin_port = htons(8888);//将linux小端转系统的大端
	my_addr.sin_addr.s_addr =inet_addr("192.168.10.5");//注意将IP地址格式转为网络二进制,还有记得改成自己的linuxIP地址
	int ret;
	ret = bind(serfd,(struct sockaddr *)&my_addr,sizeof(my_addr));
	//第二参将同族结构体强转为函数需要的结构体类型
	if(ret<0)	//错误判断
	{
		perror("bind");
		return -1;
	}
	printf("serfd网络属性已成功配置!\n");
	//3>监听
	ret = listen(serfd,8);
	if(ret<0)	//错误判断
	{
		perror("listen");
		return -1;
	}
	printf("监听已启动,保护服务器中^-^\n");
	//4>等待客户端连接 阻塞
	int clifd = accept(serfd,NULL,NULL);//accept接触阻塞后将产生一个与客户端通信的文件描述符
	if(clifd<0)	//错误判断
	{
		perror("accept");
		return -1;
	}
	printf("创建出与客户端通信的文件描述符值为%d\n",clifd);
	printf("有客户连接进来了!\n");
	//5>数据的接收
	char buf[30];
	while(1)
	{
#if 0
		bzero(buf,sizeof(buf));
		ret = recv(clifd,buf,sizeof(buf),0);//阻塞
		printf("客户端说:%s\n",buf);
#endif
		bzero(buf,sizeof(buf));
		ret = recv(clifd,buf,sizeof(buf),0);//阻塞
		if(ret<0)
		{
			perror("recv");
			return -1;
		}else if(ret == 0)
		 {
			 printf("客户带着小姨子跑了!\n");
			 return -1;
		 }else
		  {
			printf("客户端说:%s\n",buf);
		  }
	}
	//6>关闭套接字
	close(serfd);
	close(clifd);
	return 0;
}
//客户端代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>

int main(void)
{
	//1>创建socket套接字
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		perror("socket");
		return -1;
	}
	printf("创建出的socket的值为%d\n",sockfd);
	//2>声明"服务器"所在的IP地址和端口号
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(8888);
	server.sin_addr.s_addr = inet_addr("192.168.10.5");
	printf("已经声明服务器的IP地址和端口号!\n");
	//3>主动连接服务器
	int ret = connect(sockfd,(struct sockaddr*)&server,sizeof(server));
	if(ret<0)
	{
		perror("connect");
		return -1;
	}
	printf("连接服务器成功,请进行操作!\n");
	//4>数据发送
	char buf[30];
	while(1)
	{
		bzero(buf,sizeof(buf));
		scanf("%s",buf);
		send(sockfd,buf,strlen(buf),0);	
	}
	
	//5>关闭文件描述符
	close(sockfd);
	return 0;
}


Zusammenfassen

        In diesem Artikel wird die C/C++-Netzwerkprogrammierung ausführlich erläutert. Ich hoffe, er kann allen helfen!

        In Zukunft werde ich Ihnen weitere wichtige Grundkenntnisse über eingebettete und C-Sprache zeigen. Vielen Dank für die Unterstützung von Lazy King!

       Ich hoffe, dass dieser Blog allen meinen Freunden helfen kann. Schließlich werden Freunde, die von Lazy King eingeladen wurden, Ihre wertvollen Kommentare und Ihre Aufmerksamkeit hinterlassen. Vielen Dank!​  

Guess you like

Origin blog.csdn.net/weixin_58070962/article/details/133907368