Обмен технологиями

Сетевое программирование: основные понятия

2024-07-12

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

1. Модель OSI

Модель OSI ===》Модель взаимодействия открытых систем ==》разделена на 7 уровней:
Идеальная модель ==》Пока не реализована
tftp
б /etc/passwd
а /etc/123
Прикладной уровень
Шифрование и дешифрование уровня представления gzip
Отключение сети на уровне сеанса, состояние соединения, поддержание активности

Файл протокола TCP UDP транспортного уровня, видео, аудио
IP-адрес сетевого уровня NAT

Проверка кадра форматирования данных переключения канального уровня
Физический уровень 100 МБ/8 Гбит 100 МБ коаксиальный кабель 10 ГБ 2,4G 5G

Снизу вверх, внизу самое основное.

2. Модель TCP/IP

Модель TCP/IP ==》Модель Интернета ==》разделена на 4 уровня:
Практическая модель ===》Промышленный стандарт
стек протоколов tcp/ip
Прикладной уровень ====》Приложение
Транспортный уровень ====》Номер порта tcp udp (какой метод передачи используется,TCP надежныйUDP имеет высокую производительность в реальном времени.
Сетевой уровень ====》IP-адрес (Как найти другую сторону и хозяина
Уровень интерфейса ====》Драйвер сетевой карты 1 ГБ
pcap ,,,

3. Набор протоколов TCP/IP.

www.taobao.com ---> 192.168.0.19
www.voa.com vpn
Разрешение доменных имен DNS (обычно в зависимости от провинции)


DHCP (протокол динамической конфигурации хоста)
Прикладной уровень:HTTP (веб-страница) TFTP (тривиальная передача файлов на короткие расстояния)FTP (междугородняя передача через Интернет)
                   SNMP (Управление и мониторинг сетевых устройств, систем и приложений)DNS-сервер ...
Транспортный уровень: TCP UDP 56k cat
Сетевой уровень: IP ICMP (ping) RIP OSPF IGMP...
Уровень интерфейса: ARP (протокол разрешения адресов) RARP... ip ---> mac
арп,,,,
    192.160.0.112 


1. Основы сети

Основы сети ===》Класс ABCDE
010  3333344444
IP-адрес == биты сети + биты хоста

Классификация IP-адресов: десятичный с точками ipv4 712934
    Категория А: Очень масштабная сеть
                          8    8     8    8
        1.0.0.0 - 126.255.255.255  126.1.1.1 
        Идентификатор сети                                126.1.1.2
       255.0.0.0 (маска подсети)  
частный:
        10.0.0.0 - 10.255.255.255
        127.0.0.1
    Категория Б: Крупные и средние сети
        128.0.0.0 - 191.255.255.255
        128.2.1.2  128.2.7.2
        255.255.0.0
частный:
        172.16.0.0 - 172.31.255.255

   Категория С: Малые и средние сети
       192.0.0.0 - 223.255.255.255
        255.255.255.0
частный:
       192.168.0.0 - 192.168.255.255
Статическая маршрутизация
        192.168.0.0
        шлюз 192.168.0.1
        192.168.0.255 (широковещательная рассылка, ее могут получить все в локальной сети)

   Категория Д: Многоадресная рассылка итранслировать
        224.0.0.0 - 239.255.255.255 (Групповой чат, не открыт для всех, не ограничивается локальной сетью)
        192.168.0.255 == 255.255.255.255 (только LAN, отправляет один человек, получают все)
        235.1.2.3
        192.168.1.0 
192.168.0.1 Шлюз
192.168.1.255 Трансляция

Категория E: Экспериментальная
        240.0.0.0 - 255.255.255.255
        
Сеть класса С:
Первые три группы IP-адреса — это сетевой адрес, а четвертая группа — адрес хоста.
Старший бит двоичного файла должен быть: начиная с 110xxxxxx.
Диапазон десятичного представления: 192.0.0.0 -223.255.255.255.
Сетевая маска по умолчанию: 255.255.255.0.
Количество сетей: 2^24, около 2,09 миллиона.
Количество хостов: 2^8 254 + 2 ===》1 — шлюз, 1 — широковещательный.
Частный адрес: адрес локальной сети 192.168.xx.
  
  судо вим/etc/network/interfaces «Настроить сеть»
sudo /etc/init.d/networking перезапустить
перезагрузка sudo
    192.168.0.0
192.168.0.1 маршрут
192.168.0.255 boardcast
801.ng
Конфигурация для доступа в Интернет с одного компьютера:
1. Подключите сетевой интерфейс и подключите сетевой кабель.
2. Иметь IP-адрес
3. Настройте параметры сети.
           ip (изменить временный IP): ifconfig ethX XXXX/24 up ifconfig ens33 192.168.0.13/24 (маска подсети) вверх 255.255.255.0
Шлюз: маршрут добавить по умолчанию gw xxxx
DNS: vi /etc/resolv.conf ==>сервер имен 8.8.8.8
            Тест: пинг www.baidu.com
            сетьстат -anp (может просматривать состояние сети компьютера)

2. Сетевой интерфейс

1. розетка розетка (Дескриптор файла — связанное сетевое устройство) ==》BSD-сокет ==》Набор интерфейсных функций для сетевого общения..разъем апи  Интерфейс приложенияФункциональный интерфейс
        2. ip+порт адрес+порт===》Адрес используется дляОпределить хост
Используемый портОпределение приложений

          Порт разделен на TCP-порт/UDP-порт, диапазон: 1-65535.
Согласовано, что системой используются порты в пределах 1000.
http 80 www.baidu.com
                3306
телнет 21
сш 22

3. Порядок сетевых байтов

        Хранилище с прямым порядком байтов (младшие биты в верхней памяти — сетевые устройства)
     Little endian 0x12345678 (младший бит в нижней памяти — хост)
        12 00   
        00 12
        192.168.0.12 (обратный порядок байтов) «старший бит сохраняется первым»
       12.0.168.192 (с прямым порядком байтов)

4. UDP (пользовательская датаграмма)

1. Особенности: нет ссылки, ненадежно, большие данные.

2. Структура: режим C/S

сервер:socket() ===>bind()===>recvfrom()===>close()
клиент:socket() ===>bind()===>sendto() ===>close()

Примечание. Параметры сокета() необходимо настроить.

сокет(PF_INET,SOCK_DGRAM,0);

      client() (c) не является обязательнымТребуется серверная часть(и)

1.розетка

сокет int(домен int, тип int, протокол int);
Функция: Программа предлагает ядруСоздание дескриптора сокета на основе памяти

параметр:семейство адресов домена, PF_INET == AF_INET ==>Интернет-программа
PF_UNIX == AF_UNIX ==>автономная программа

          тип Тип розетки:
Потоковый сокет SOCK_STREAM ===》TCP
SOCK_DGRAM Сокет пользовательских датаграмм ===>UDP
SOCK_RAW необработанный сокет ===》IP

          протокол протокол ==》0 означает автоматическую адаптацию к протоколу прикладного уровня.

Возвращаемое значение: возврат успешноЗапрошенный идентификатор сокета
Неудача -1;

2.связать

int привязать(инт sockfd, структура sockaddr *my_addrsocklen_t адрес);
Функция: Если функция находится вСервис-ТерминалВызывается, это значит связать файл дескриптора файла, относящийся к параметру 1, с адресом интерфейса, указанным параметром 2 дляПринять данные из этого интерфейса

Если функция находится вКлиентская настройкаЕсли используется, это означает, что данные должны быть извлечены из дескриптора, где находится параметр 1, и из интерфейсного устройства, где находится параметр 2. Отправить

Примечание. Если это клиент, эту функцию можно опустить, и данные будут отправлены через интерфейс по умолчанию.
параметр:дескриптор файла sockfd и идентификатор сокета, ранее созданный с помощью функции сокета
          my_addr — указатель структуры физического интерфейса.Представляет информацию об интерфейсе

struct sockaddr универсальная структура адреса
      {
u_short sa_family адресов;
информация об адресе char sa_data[14];
      };

Преобразованная структура сетевого адреса выглядит следующим образом:
struct _sockaddr_in ///Структура сетевого адреса
      {
u_short sin_family адресов;
u_short sin_port; ///Адресный порт;
struct in_addr sin_addr ///IP-адрес
символ sin_zero[8];
      };

структура in_addr
      {
in_addr_t s_addr;
      }

socklen_t addrlen: длина параметра 2.
Возвращаемое значение: успех 0
Неудача -1;

3.Отправитьперениматьфункция:

ssize_t отправить(инт sockfd, константа void *buf, size_t длина,флаги int,
                       
константная структура sockaddr *dest_addr, socklen_t адрес);

Функция: используется для отправки сообщений другой стороне по протоколу UDP.отправить данные
параметр:идентификатор локального сокета sockfd
           усилить локальное хранилище данных, обычно данные, которые нужно отправить
          len длина данных для отправки
          флаги Как отправить данные,0 означает блокировку отправки

          dest_addr: обязательный, указывающий структуру информации о целевом хосте, на которую будет отправлена
        addrlen: длина целевого адреса

Возвращаемое значение: Успех. Длина отправленных данных.
Неудача -1;


ssize_t получить из(инт sockfd, пустота *буф, size_t длина, флаги int,
                          
структура sockaddr *src_addr, socklen_t *addrlen);

Функция: используется в протоколе UDPПолучатьДанные, отправленные другой стороной.
параметр:идентификатор локального сокета sockfd
          buff Область памяти, в которой должны храниться данные, обычно массив или динамическая память.
        len — длина получаемых данных, обычно размер баффа.
           метод получения флагов,0 блокировок

          src_addr является необязательным и представляет структуру информации об адресе другой стороны.НУЛЕВОЙ,выражатьНе заботьтесь об адресе другой стороны
          addrlen Размер информационной структуры адреса другой стороны, еслиАдрес другой стороныдаНУЛЕВОЙЛ, тогдаЭто значение также равно NULL
Возвращаемое значение: длина успешно полученных данных.
Неудача -1;

4.Закрыть

закрывать() ===>Закрыть указанный идентификатор сокета;


Уведомление

1. Данные и данные имеют границы
2. Количество отправок и приёмов должно совпадать.
3.recvfrom заблокирует
4.sento не будет блокироваться (recvfrom не получает, не влияет на отправку sendo) 


   c ищет s

сервер.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. }

клиент.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. }