Condivisione della tecnologia

Programmazione di rete: concetti di base

2024-07-12

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

1. Modello OSI

Modello OSI ===》Modello di interconnessione del sistema aperto ==》è diviso in 7 livelli:
Modello ideale ==》Non ancora realizzato
tftp
il file /etc/passwd
un /etc/123
Livello di applicazione
Crittografia e decrittografia del livello di presentazione gzip
Disconnessione della rete a livello di sessione, stato della connessione, keep-close keep-alive

Livello di trasporto file di protocollo tcp udp video, audio
IP NAT del livello di rete

Controllo del frame di formattazione dei dati del cambio del livello di collegamento
Strato fisico 100 Mb/8 Gbit Cavo coassiale 100 MB 10 Gb 2,4 G 5G

Dal basso verso l'alto, il fondo è il più elementare

2. Modello TCP/IP

Modello TCP/IP ==》Modello Internet ==》è diviso in 4 livelli:
Modello pratico ===》Standard industriale
stack di protocolli tcp/ip
Livello applicazione ====》Applicazione
Livello di trasporto ====》Numero di porta tcp udp (quale metodo di trasmissione viene utilizzato,TCP affidabileUDP ha elevate prestazioni in tempo reale
Livello di rete ====》Indirizzo IP (Come trovare l'altra parte e l'ospite
Livello interfaccia ====》Driver della scheda di rete 1 GB
cappa ,,,

3. Suite di protocolli TCP/IP

www.taobao.com ---> 192.168.0.19
www.voa.com vpn
Risoluzione dei nomi di dominio DNS (generalmente in base alla provincia)


DHCP (protocollo di configurazione host dinamico)
Livello di applicazione:HTTP (pagina web) TFTP (trasferimento file a corto raggio banale)FTP (trasferimento Internet a lunga distanza)
                   SNMP (Gestione e monitoraggio di dispositivi, sistemi e applicazioni di rete)...il nome DNS è ...
Livello di trasporto: TCP UDP 56k cat
Livello di rete: IP ICMP (ping) RIP OSPF IGMP...
Livello di interfaccia: ARP (protocollo di risoluzione degli indirizzi) RARP... ip--->mac
arp,,,,
    192.160.0.112 


1. Nozioni di base sulla rete

Nozioni di base sulla rete ===》Classe ABCDE
010  3333344444
Indirizzo IP == bit di rete + bit host

Classificazione indirizzo IP: decimale puntato ipv4 712934
    Categoria A: Rete su larga scala
                          8    8     8    8
        1.0.0.0 - 126.255.255.255  126.1.1.1 
        ID di rete                                126.1.1.2
       255.0.0.0 (maschera di sottorete)  
privato:
        10.0.0.0 - 10.255.255.255
        127.0.0.1
    Categoria B: Reti di grandi e medie dimensioni
        128.0.0.0 - 191.255.255.255
        128.2.1.2  128.2.7.2
        255.255.0.0
privato:
        172.16.0.0 - 172.31.255.255

   Categoria C: Reti di piccole e medie dimensioni
       192.0.0.0 - 223.255.255.255
        255.255.255.0
privato:
       192.168.0.0 - 192.168.255.255
Instradamento statico
        192.168.0.0
        Porta 192.168.0.1
        192.168.0.255 (Trasmissione, tutti sulla LAN possono riceverla)

   Categoria D: Multicast etrasmissione
        224.0.0.0 - 239.255.255.255 (Chat di gruppo, non aperta a tutti, non limitata alla LAN)
        192.168.0.255 == 255.255.255.255 (solo LAN, una persona invia, tutti ricevono)
        235.1.2.3
        192.168.1.0 
192.168.0.1 Portale
192.168.1.255 Trasmissione

Categoria E: Sperimentale
        240.0.0.0 - 255.255.255.255
        
Rete di classe C:
I primi tre gruppi dell'indirizzo IP rappresentano l'indirizzo di rete e il quarto gruppo è l'indirizzo host.
Il bit più alto del codice binario deve essere: iniziare con 110xxxxx
Intervallo di rappresentazione decimale: 192.0.0.0 -223.255.255.255
Maschera di rete predefinita: 255.255.255.0
Numero di reti: 2^24, circa 2,09 milioni
Numero di host: 2^8 254 + 2 ===》1 è il gateway 1 viene trasmesso
Indirizzo privato: indirizzo LAN 192.168.xx.
  
  sudo vim/etc/network/interfaces "Configura rete"
sudo /etc/init.d/networking riavvia
sudo riavvia
    192.168.0.0
percorso 192.168.0.1
trasmissione in diretta 192.168.0.255
801.ng
Configurazione per l'accesso a Internet su una sola macchina:
1. Disporre di un'interfaccia di rete e collegare il cavo di rete.
2. Avere un indirizzo IP
3. Configurare le impostazioni di rete
           ip (modifica ip temporaneo): ifconfig ethX XXXX/24 up ifconfig ens33 192.168.0.13/24 (maschera di sottorete) su 255.255.255.0
Gateway: percorso aggiungi predefinito gw xxxx
DNS: vi /etc/resolv.conf ==>nameserver 8.8.8.8
            Prova: ping www.baidu.com
            nettostatistica -anp (può visualizzare lo stato della rete del computer)

2. Interfaccia di rete

1. presa presa (Descrittore di file: dispositivo di rete associato) ==》Socket BSD ==》Un insieme di funzioni di interfaccia per la comunicazione di rete.PRESA API  interfaccia delle funzioni dell'interfaccia dell'applicazione
        2. indirizzo IP+porta indirizzo+porta===》L'indirizzo è utilizzatoIdentificare l'ospite
Porto utilizzatoIdentificare le applicazioni

          La porta è divisa in porta TCP/porta UDP, l'intervallo è: 1-65535
Si concorda che il sistema utilizzerà le porte comprese tra 1000 e 1000.
http 80 www.baidu.com
                3306
telnet21
ssh22

3. Ordine dei byte di rete

        Archiviazione big endian (bit bassi in memoria elevata - dispositivi di rete)
     Little endian 0x12345678 (bit basso in memoria insufficiente - host)
        12 00   
        00 12
        192.168.0.12 (big-endian) "bit più significativo memorizzato per primo"
       12.0.168.192 (little endian)

4. UDP (Datagramma utente)

1. Caratteristiche: nessun collegamento, inaffidabile, big data

2. Quadro: modalità C/S

server:socket() ===>bind()===>recvfrom()===>close()
client:socket() ===>bind()===>sendto() ===>close()

Nota: i parametri di socket() devono essere modificati.

socket(PF_INET,SOCK_DGRAM,0);

      bind() client(c) è facoltativoI lati server sono obbligatori

1.presa

presa interna(dominio int, tipo int, protocollo int);
Funzione: Il programma propone al kernelCreare un descrittore di socket basato sulla memoria

parametro:famiglia di indirizzi di dominio, PF_INET == AF_INET ==>Programma Internet
PF_UNIX == AF_UNIX ==>programma autonomo

          tipo tipo di presa:
Socket streaming SOCK_STREAM ===》TCP
SOCK_DGRAM Socket datagramma utente ===>UDP
Socket grezzo SOCK_RAW ===》IP

          protocollo protocollo ==》0 significa adattarsi automaticamente al protocollo del livello di applicazione.

Valore restituito: restituito con successoL'ID del socket richiesto
Fallimento -1;

2.legare

int lega(int calzino, struct sockaddr *mio_indirizzosocklen_t addrlen);
Funzione: se la funzione è attivaTerminale di servizioChiamato significa associare il file descrittore relativo al parametro 1 all'indirizzo di interfaccia specificato dal parametro 2 perAccetta i dati da questa interfaccia

Se la funzione è inSintonizzazione del clienteSe utilizzato significa che i dati devono essere prelevati dal descrittore dove si trova il parametro 1 e dal dispositivo di interfaccia dove si trova il parametro 2. spedito

Nota: se si tratta di un client, questa funzione può essere omessa e i dati verranno inviati tramite l'interfaccia predefinita.
parametro:descrittore del file sockfd e ID socket precedentemente creati tramite la funzione socket
          my_addr è il puntatore alla struttura dell'interfaccia fisica.Rappresenta informazioni sull'interfaccia

struct sockaddr struttura universale degli indirizzi
      {
u_short sa_family; indirizzo famiglia
char sa_data[14]; informazioni sull'indirizzo
      };

La struttura dell'indirizzo di rete convertito è la seguente:
struct _sockaddr_in ///Struttura dell'indirizzo di rete
      {
u_short sin_family; indirizzo famiglia
u_short sin_port; ///Indirizzo porta
struct in_addr sin_addr; ///Indirizzo IP
char sin_zero[8];
      };

struttura in_addr
      {
in_addr_t s_indirizzo;
      }

socklen_t addrlen: la lunghezza del parametro 2.
Valore restituito: successo 0
Fallimento -1;

3.Inviarilevarefunzione:

ssize_t invia a(int calzino, costante vuoto *buf, size_t lunghezza,bandiere int,
                       
const struct sockaddr *dest_addr, socklen_t addrlen);

Funzione: Utilizzato per inviare messaggi all'interlocutore nel protocollo UDPinvia i dati
parametro:ID del socket locale sockfd
           potenziare l'archiviazione locale dei dati, solitamente i dati da inviare
          lunghezza dei dati da inviare
          flag Come inviare i dati,0 significa bloccare l'invio

          dest_addr: obbligatorio, indica la struttura informativa dell'host di destinazione a cui inviare
        addrlen: lunghezza dell'indirizzo di destinazione

Valore restituito: successo Lunghezza dati inviata
Fallimento -1;


ssize_t ricevuto da(int calzino, vuoto *buf, size_t lunghezza, bandiere int,
                          
struct sockaddr *src_addr, socklen_t *addrlen);

Funzione: utilizzata nel protocollo UDPOttenereI dati inviati dall'altra parte.
parametro:ID del socket locale sockfd
          buff L'area di memoria in cui devono essere archiviati i dati, solitamente un array o una memoria dinamica
        len è la lunghezza dei dati da ottenere, solitamente la dimensione del buff.
           metodo di acquisizione dei flag,0 blocco

          src_addr è facoltativo e rappresenta la struttura delle informazioni sull'indirizzo dell'altra parte IfNULLO,esprimereNon preoccuparti dell'indirizzo dell'altra parte
          addrlen La dimensione della struttura delle informazioni sull'indirizzo dell'altra parte, seIndirizzo dell'altra parteNULLAL, alloraAnche questo valore è NULL
Valore restituito: lunghezza dei dati ricevuti con successo
Fallimento -1;

4.Chiudi

vicino() ===>Chiude l'id del socket specificato;


Avviso

1. Dati e dati hanno confini
2. Il numero di invii e ricevimenti deve corrispondere
3.recvfrom verrà bloccato
4.sento non si bloccherà (recvfrom non riceve, non influisce sull'invio di sento) 


   c cerca 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. }

cliente.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. }