Technologieaustausch

Netzwerkprogrammierung: Grundkonzepte

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. OSI-Modell

Das OSI-Modell ===》Open System Interconnection Model ==》ist in 7 Schichten unterteilt:
Ideales Modell ==》Noch nicht realisiert
TFTP
b /etc/passwd
ein /etc/123
Anwendungsschicht
Verschlüsselung und Entschlüsselung der Präsentationsschicht gzip
Netzwerktrennung auf Sitzungsebene, Verbindungsstatus, Keep-Close-Keep-Alive

Transportschicht-TCP-UDP-Protokolldatei, Video, Audio
IP-NAT der Netzwerkschicht

Überprüfung des Link-Layer-Switch-Datenformatierungsrahmens
Physikalische Schicht 100 MB/8 Gbit/s, 100 MB Koaxialkabel, 10 GB, 2,4 G, 5 G

Von unten nach oben ist die Unterseite die einfachste

2. TCP/IP-Modell

Das TCP/IP-Modell ==》Internetmodell ==》ist in 4 Schichten unterteilt:
Praktisches Modell ===》Industriestandard
TCP/IP-Protokollstapel
Anwendungsschicht ====》Anwendung
Transportschicht ====》Portnummer TCP UDP (welche Übertragungsmethode verwendet wird,TCP zuverlässigUDP verfügt über eine hohe Echtzeitleistung
Netzwerkschicht ====》IP-Adresse (So finden Sie die andere Partei und den Gastgeber
Schnittstellenschicht ====》Netzwerkkartentreiber 1 GB
pcap ,,,

3. TCP/IP-Protokollsuite

www.taobao.com ---> 192.168.0.19
www.voa.com VPN
Auflösung von DNS-Domänennamen (im Allgemeinen basierend auf der Provinz)


DHCP (Dynamic Host Configuration Protocol)
Anwendungsschicht:HTTP (Webseite) TFTP (triviale Nahbereichsdateiübertragung)FTP (Internet-Fernübertragung)
                   SNMP (Netzwerkgeräte, -systeme und -anwendungen verwalten und überwachen)DNS ...
Transportschicht: TCP UDP 56k Kat
Netzwerkschicht: IP ICMP (Ping) RIP OSPF IGMP...
Schnittstellenschicht: ARP (Address Resolution Protocol) RARP... ip--->mac
arp,,,,
    192.160.0.112 


1. Netzwerkgrundlagen

Netzwerkgrundlagen ===》ABCDE-Klasse
010  3333344444
IP-Adresse == Netzwerkbits + Hostbits

IP-Adressklassifizierung: Punkt-Dezimal-IPv4 712934
    Kategorie A: Sehr großes Netzwerk
                          8    8     8    8
        1.0.0.0 - 126.255.255.255  126.1.1.1 
        Netzwerk ID                                126.1.1.2
       255.0.0.0 (Subnetzmaske)  
Privat:
        10.0.0.0 - 10.255.255.255
        127.0.0.1
    Kategorie B: Große und mittlere Netzwerke
        128.0.0.0 - 191.255.255.255
        128.2.1.2  128.2.7.2
        255.255.0.0
Privat:
        172.16.0.0 - 172.31.255.255

   Kategorie C: Kleine und mittlere Netzwerke
       192.0.0.0 - 223.255.255.255
        255.255.255.0
Privat:
       192.168.0.0 - 192.168.255.255
Statisches Routing
        192.168.0.0
        192.168.0.1 Gateway
        192.168.0.255 (Broadcast, jeder im LAN kann es empfangen)

   Kategorie D: Multicast undübertragen
        224.0.0.0 - 239.255.255.255 (Gruppenchat, nicht für jedermann zugänglich, nicht auf LAN beschränkt)
        192.168.0.255 == 255.255.255.255 (nur LAN, eine Person sendet, jeder empfängt)
        235.1.2.3
        192.168.1.0 
192.168.0.1 Gateway
192.168.1.255 Übertragung

Kategorie E: Experimentell
        240.0.0.0 - 255.255.255.255
        
Klasse-C-Netzwerk:
Die ersten drei Gruppen der IP-Adresse sind die Netzwerkadresse und die vierte Gruppe ist die Hostadresse.
Das höchste Bit der Binärdatei muss sein: beginnend mit 110xxxxx
Dezimaldarstellungsbereich: 192.0.0.0 -223.255.255.255
Standardnetzmaske: 255.255.255.0
Anzahl der Netzwerke: 2^24, etwa 2,09 Millionen
Anzahl der Hosts: 2^8 254 + 2 ===》1 ist Gateway 1 wird gesendet
Private Adresse: 192.168.xx LAN-Adresse.
  
  sudo vim/etc/network/interfaces „Netzwerk konfigurieren“
sudo /etc/init.d/networking Neustart
sudo Neustart
    192.168.0.0
Route 192.168.0.1
192.168.0.255 Boardcast
801.ng
Konfiguration für Einzelrechner-Internetzugang:
1. Verfügen Sie über eine Netzwerkschnittstelle und schließen Sie das Netzwerkkabel an.
2. Haben Sie eine IP-Adresse
3. Konfigurieren Sie die Netzwerkeinstellungen
           IP (temporäre IP ändern): ifconfig ethX XXXX/24 up ifconfig ens33 192.168.0.13/24 (Subnetzmaske) bis 255.255.255.0
Gateway: Route fügt Standard-GW xxxx hinzu
DNS: vi /etc/resolv.conf ==>Nameserver 8.8.8.8
            Test: ping www.baidu.com
            NetzStatistik -anp (kann den Netzwerkstatus des Computers anzeigen)

2. Netzwerkschnittstelle

1. Steckdose (Dateideskriptor – zugehöriges Netzwerkgerät) ==》BSD-Socket ==》Eine Reihe von Schnittstellenfunktionen für die Netzwerkkommunikation.Steckdose API  AnwendungsschnittstelleFunktionsschnittstelle
        2. IP-Adresse+Hafen Adresse+Hafen===》Die Adresse wird verwendetHost identifizieren
Verwendeter PortAnwendungen identifizieren

          Der Port ist in TCP-Port/UDP-Port unterteilt, der Bereich ist: 1-65535
Es wird vereinbart, dass Ports innerhalb von 1000 vom System verwendet werden.
http 80 www.baidu.com
                3306
Telnet 21
ssh 22

3. Netzwerk-Byte-Reihenfolge

        Big-Endian-Speicher (niedrige Bits im hohen Speicher – Netzwerkgeräte)
     Little Endian 0x12345678 (niedriges Bit in wenig Arbeitsspeicher – Host)
        12 00   
        00 12
        192.168.0.12 (Big-Endian) „höchstes Bit wird zuerst gespeichert“
       12.0.168.192 (Little Endian)

4. UDP (Benutzerdatagramm)

1. Merkmale: Kein Link, unzuverlässig, große Datenmengen

2. Framework: C/S-Modus

Server: Socket () ===> Binden () ===> Empfangen von () ===> Schließen ()
Client: Socket () ===> Binden () ===> Senden an () ===> Schließen ()

Hinweis: Die Parameter von socket() müssen angepasst werden.

Socket (PF_INET, SOCK_DGRAM, 0);

      bind() client(c) ist optionalServerseite(n) sind erforderlich

1.Buchse

int-Socket(int-Domäne, int-Typ, int-Protokoll);
Funktion: Das Programm schlägt dem Kernel vorErstellen Sie einen speicherbasierten Socket-Deskriptor

Parameter:Domänenadressfamilie, PF_INET == AF_INET ==>Internetprogramm
PF_UNIX == AF_UNIX ==>eigenständiges Programm

          Typ Steckdosentyp:
SOCK_STREAM-Streaming-Socket ===》TCP
SOCK_DGRAM Benutzer-Datagramm-Socket ===>UDP
SOCK_RAW Raw-Socket ===》IP

          Protokoll Protokoll ==》0 bedeutet automatische Anpassung an das Protokoll der Anwendungsschicht.

Rückgabewert: Erfolgreiche RückgabeDie angeforderte Socket-ID
Fehler -1;

2.binden

int bind(int sockfd, Struktur sockaddr *meine_Adressesocklen_t addrlen);
Funktion: Wenn die Funktion vorhanden istService-TerminalDies bedeutet, dass die Dateideskriptordatei, die sich auf Parameter 1 bezieht, mit der durch Parameter 2 angegebenen Schnittstellenadresse verknüpft wirdAkzeptieren Sie Daten von dieser Schnittstelle

Wenn die Funktion vorhanden istKundenstimmenBei Verwendung bedeutet dies, dass die Daten aus dem Deskriptor entnommen werden sollten, in dem sich Parameter 1 befindet, und aus dem Schnittstellengerät, in dem sich Parameter 2 befindet. aussenden

Hinweis: Wenn es sich um einen Client handelt, kann diese Funktion weggelassen werden und die Daten werden über die Standardschnittstelle gesendet.
Parameter:Sockfd-Dateideskriptor und Socket-ID, die zuvor über die Socket-Funktion erstellt wurden
          my_addr ist der Strukturzeiger der physischen Schnittstelle.Stellt Informationen über die Schnittstelle dar

struct sockaddr universelle Adressstruktur
      {
u_short sa_family; Adressfamilie
char sa_data[14]; Adressinformationen
      };

Die konvertierte Netzwerkadressstruktur sieht wie folgt aus:
struct _sockaddr_in ///Netzwerkadressstruktur
      {
u_short sin_family; Adressfamilie
u_short sin_port; ///Adressport
struct in_addr sin_addr; ///Adresse IP
char sin_zero[8]; Platzhalter
      };

Struktur in_addr
      {
in_addr_t s_addr;
      }

socklen_t addrlen: die Länge von Parameter 2.
Rückgabewert: Erfolg 0
Fehler -1;

3.SendenübernehmenFunktion:

ssize_t sendto(int sockfd, const void *buf, size_t Länge,int-Flags,
                       
const struct sockaddr *Zieladresse, socklen_t addrlen);

Funktion: Wird verwendet, um Nachrichten im UDP-Protokoll an die andere Partei zu sendenDaten senden
Parameter:sockfd lokale Socket-ID
           Buff lokaler Datenspeicher, normalerweise die zu sendenden Daten
          Länge der zu sendenden Daten
          flags So senden Sie Daten,0 bedeutet, dass das Senden blockiert wird

          dest_addr: erforderlich, gibt die Ziel-Host-Informationsstruktur an, an die gesendet werden soll
        addrlen: Länge der Zieladresse

Rückgabewert: Erfolgreiche Datenlänge gesendet
Fehler -1;


ssize_t Empfang von(int sockfd, void *buf, size_t Länge, int-Flags,
                          
Struktur sockaddr *src_addr, socklen_t *addrlen);

Funktion: Wird im UDP-Protokoll verwendetErhaltenDie von der anderen Partei gesendeten Daten.
Parameter:sockfd lokale Socket-ID
          Buff Der Speicherbereich, in dem Daten gespeichert werden sollen, normalerweise ein Array oder ein dynamischer Speicher
        len ist die Länge der zu erhaltenden Daten, normalerweise die Größe des Buffs.
           Flags-Erfassungsmethode,0 Blockierung

          src_addr ist optional und stellt die Adressinformationsstruktur der anderen Partei darNULL,äußernDie Adresse der anderen Partei ist Ihnen egal
          addrlen Die Größe der Adressinformationsstruktur der anderen Partei, fallsAdresse der anderen ParteiJaNULL, dannAuch dieser Wert ist NULL
Rückgabewert: Länge der erfolgreich empfangenen Daten
Fehler -1;

4.Schließen

schließen() ===>Schließen Sie die angegebene Socket-ID;


Beachten

1. Daten und Daten haben Grenzen
2. Die Anzahl der Sende- und Empfangsvorgänge sollte übereinstimmen
3.recvfrom wird blockiert
4. Sento blockiert nicht (recvfrom empfängt nicht, hat keinen Einfluss auf das Sento-Versenden) 


   c sucht nach s

server.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <time.h>
  10. typedef struct sockaddr *SA;
  11. int main(int argc, char *argv[])
  12. {
  13. int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建一个UDP套接字
  14. if(-1 == sockfd) // 检查socket调用是否失败
  15. {
  16. perror("socket"); // 打印错误信息
  17. exit(1); // 退出程序
  18. }
  19. // 定义服务器地址和客户端地址结构体(尽管客户端地址通常在recvfrom中填充)
  20. struct sockaddr_in ser, cli;
  21. bzero(&ser, sizeof(ser)); // 初始化服务器地址结构体
  22. bzero(&cli, sizeof(cli)); // 初始化客户端地址结构体(但这里实际上不需要提前初始化)
  23. // 设置服务器地址结构体
  24. ser.sin_family = AF_INET;
  25. ser.sin_port = htons(50000); // 端口号转换为网络字节序
  26. ser.sin_addr.s_addr = inet_addr("192.168.203.128"); // 服务器IP地址
  27. // 将套接字绑定到服务器地址和端口
  28. int ret = bind(sockfd, (SA)&ser, sizeof(ser));
  29. if(-1 == ret)
  30. {
  31. perror("bind"); // 绑定失败时打印错误信息
  32. exit(1); // 退出程序
  33. }
  34. socklen_t len = sizeof(cli); // 用于recvfrom的客户端地址长度
  35. // 无限循环接收数据并发送响应
  36. while(1)
  37. {
  38. char buf[512] = {0}; // 准备接收数据的缓冲区
  39. // 接收数据,注意这里&len是必需的,因为recvfrom会修改它以反映实际接收到的客户端地址长度
  40. recvfrom(sockfd, buf, sizeof(buf), 0, (SA)&cli, &len);
  41. time_t tm;
  42. time(&tm); // 获取当前时间
  43. // 这里有一个问题:buf被用于接收数据,然后又被用于存储新的字符串(包括原始数据和时间戳)
  44. // 这会导致原始数据被覆盖。应该使用另一个缓冲区来存储最终的发送数据
  45. sprintf(buf, "%s %s", buf, ctime(&tm)); // 将时间戳附加到接收到的数据上
  46. // 发送数据回客户端,但注意len在这里已经被recvfrom修改,表示客户端地址的长度
  47. // 对于sendto,我们应该使用sizeof(cli)或重新初始化len
  48. sendto(sockfd, buf, strlen(buf), 0, (SA)&cli, len); // 这里使用len可能不是最佳实践
  49. }
  50. // 注意:由于程序进入了一个无限循环,下面的close和return语句实际上永远不会被执行
  51. close(sockfd); // 正常情况下应该关闭套接字
  52. return 0; // 程序正常结束
  53. }

client.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h> /* See NOTES */
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <netinet/ip.h>
  9. #include <arpa/inet.h>
  10. #include <time.h>
  11. // 定义一个类型别名SA,指向sockaddr结构体
  12. typedef struct sockaddr *SA;
  13. // 注意:它尝试定义一个函数指针类型而不是简单的结构体指针。
  14. int main(int argc, char *argv[])
  15. {
  16. // 创建一个UDP套接字
  17. int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  18. if(-1 == sockfd)
  19. {
  20. perror("socket"); // 如果创建套接字失败,打印错误信息
  21. exit(1); // 退出程序
  22. }
  23. // 初始化sockaddr_in结构体,用于指定服务器地址和端口
  24. struct sockaddr_in ser;
  25. bzero(&ser, sizeof(ser)); // 将结构体内存清零
  26. ser.sin_family = AF_INET; // 使用IPv4地址
  27. // 将端口号从主机字节序转换为网络字节序
  28. ser.sin_port = htons(50000);
  29. // 将点分十进制的IP地址字符串转换为网络字节序的整数
  30. ser.sin_addr.s_addr = inet_addr("192.168.203.128");
  31. // 无限循环,发送数据并尝试接收响应
  32. while(1)
  33. {
  34. char buf[512] = "hello,this is udp test"; // 准备发送的数据
  35. // 发送数据到指定的服务器地址和端口
  36. sendto(sockfd, buf, strlen(buf), 0, (SA)&ser, sizeof(ser));
  37. // 清空缓冲区,准备接收数据
  38. bzero(buf, sizeof(buf));
  39. // 尝试接收数据,但源地址和端口被设置为NULL,这通常是不正确的
  40. // 在实际应用中,应该提供一个sockaddr_in结构体来接收源地址和端口信息
  41. recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
  42. // 打印接收到的数据(但在这个例子中,由于recvfrom的源地址和端口被设置为NULL,它可能不会按预期工作)
  43. printf("buf is %sn", buf);
  44. // 等待1秒后再发送下一个数据包
  45. sleep(1);
  46. }
  47. // 注意:由于程序进入了一个无限循环,下面的close和return语句实际上永远不会被执行
  48. close(sockfd); // 关闭套接字
  49. return 0; // 程序正常结束
  50. }