Задать вопрос
  • Как на pfsense настроить сразу 5 провайдеров?

    @res2001
    Developer, ex-admin
    Похоже pfSense начала что-то уметь в этом вопросе. Смотрите тут: https://docs.netgate.com/pfsense/en/latest/multiwa...
    Ответ написан
    Комментировать
  • Как отправить UDP пакет через командную строку Linux?

    @res2001
    Developer, ex-admin
    или объясните почему ни чего ен получится?

    Потому что передача по сети - это протокол обмена. И это не UDP или TCP, это протокол более высокого уровня. Протокол обмена должны поддерживать обе стороны, иначе это будет разговор слепого с глухим. Протокол включает в себя формат пакета/потока (список данных, описание данных и двоичного представления этих данных). Без знания протокола вряд ли получится что-то передать так, что бы принимающая сторона это восприняла как свой родной пакет и предприняла бы соответствующие действия.
    Протоколы могут быть двоичные и текстовые. В текстовом протоколе (HTTP, SMTP, ...) визуально видны части пакета и в принципе по анализу перехваченных данных можно сделать какие-то выводы.
    В двоичном протоколе без описания формата вряд ли что-то можно разобрать. Разве что что-то очень простое. У вас двоичный протокол.
    Поэтому, обычно, что бы что-то отправить по какому-то протоколу требуется специализированная утилита, реализующая этот протокол. Например для HTTP утилита - это браузер или какой-нибудь curl.
    Бывает, что протокол открытый, т.е. описание доступно в свободном доступе (или его можно купить). Так же часто используются закрытые протоколы, описание которых есть только у его разработчиков. Если у вас открытый протокол то шансы что-то скостылить есть.

    Поищите у производителя устройства (спросите на форуме поддержки) фирменную утилиту работающую из командной строки или описание протокола (или конкретно данного пакета для установки времени).

    Раз у вас пакет установки времени, то в данных должно присутствовать время. Это может быть какой-то вариант timestamp, например Unix timestamp. Можете попробовать поискать в дампе таймстамп на момент отправки пакета. Имея несколько вариантов пакета можно попытаться сделать какой-то его анализ и попробовать разобрать пакет на составляющие его поля. Сделать реверс инжиниринг.

    Еще немного. Обычно для установки времени не достаточно просто отправить 1 пакет с новым временем. Т.е. можно и так, конечно. Но в этом случае потенциально может быть большая не точность, т.к. доставка пакета не моментальна, могут быть задержки при передаче и приеме и все это практически не предсказуемо. И когда приемная сторона установит у себя полученное время, то это время уже может стать не точным. Поэтому для минимизации побочных эффектов задержек используют отдельные протоколы для установки времени и там уже как правило не один пакет.
    Для примера можете немного посмотреть в сторону протокола NTP - он используется для синхронизации времени через интернет, это открытый протокол, доступно его описание. Например ваша винда наверняка синхронизируется с каким-то NTP сервером от микрософт, фиг знает где находящимся.
    Ответ написан
    Комментировать
  • Что лучше использовать словарь или массив или связный список?

    @res2001
    Developer, ex-admin
    Надо знать достоинства и недостатки каждого контейнера и решить какие требования к контейнеру предъявляет конкретная задача (какие операции контейнера будут критичными для конкретной задачи).

    1. Массив (не отсортированный)
    Плюсы: доступ к элементу по индексу - O(1)
    Минусы: произвольный поиск - O(n); вставка, удаление - O(n) требуется перевыделение памяти и копирование всего контейнера
    2. Список
    Плюсы: вставка - если известно место вставки O(1); удаление - если известен удаляемый элемент O(1)
    Минусы: доступ по индексу, произвольный поиск - O(n);
    3. Словарь
    Может быть внутри реализован как дерево или как хеш-таблица. Как реализованы в питоне стандартный объект не знаю.
    3.1. Дерево. Обычно используется какой-то вариант сбалансированных двоичных деревьев поиска (красно-черное и т.п.)
    Плюсы: произвольный поиск, вставка, удаление - O(log(n))
    Минусы: для обеспечения сбалансированности дерева используются дополнительные "внутренние" операции с деревом, что увеличивает время каждой отдельно взятой операции вставки и удаления. Эти операции обычно достаточно "легкие" и константные по времени.
    3.2. Хеш-таблица
    Плюсы: произвольный поиск, вставка, удаление - O(1);
    Минусы: вставка и удаление могут в некоторых случаях приводить к перевыделению памяти и полному копированию и/или к пересчету хешей в зависимости от реализации.

    Как видите, нет универсального 100% подходящего контейнера на все случаи жизни. У всех есть свои плюсы и минусы.
    Ответ написан
    Комментировать
  • Как переименовать все файлы в нижний регистр с помощью cmd?

    @res2001
    Developer, ex-admin
    осложняется древним багом Windows

    Это не баг. Это фича. В WinAPI имена файлов регистронезависимые. Поэтому и нельзя переименовать, т.к. с точки зрения WinAPI это одно и то же имя.

    Вместо переименования с добавлением левого рандомного символа, предлагаю переносить в %TEMP% с одновременным изменением имени файла. Затем переносить обратно. Возможно переносить надо не в TEMP, а в другой каталог. Нужно что бы каталоги были на одном диске, чтоб не было реального копирования файлов. Может быть создавать тут же пустой временный каталог, так вы сможете гарантировать, что во временном каталоге не будет файлов с таким же именем.
    Ответ написан
    Комментировать
  • Почему происходит односторонняя потеря пакетов между двумя пк?

    @res2001
    Developer, ex-admin
    Вы с другом находитесь в одном городе?
    Если да, то, по идее, вы находитесь в одной провайдерской сети. Задержки должны быть минимальными при доступе друг к другу.

    Сделайте traceroute (tracert/mtr) с обоих компов друг к другу, сравните вывод, посмотрите через какие адреса проходит трафик в обоих случаях. Где происходят самые большие задержки. В нормальном состоянии трафик должен идти через одни и те же промежуточные хосты и даже может не выходить за пределы провайдерской сети. Если набор промежуточных хостов сильно различается, то возможно провайдер криво маршрутизирует трафик и он в одном из случае идет по какому-то не оптимальному маршруту. Если на одном из узлов с одной стороны задержки приемлемые, а с другой высокие - явно что-то не то с этим узлом.
    Можно звонить в поддержку и попытаться объяснить ситуацию, давя на проведенное вами исследование. Как минимум пожаловаться на неадекватные задержки внутри провайдерской сети.

    Для большей достоверности traceroute стоит запустить несколько раз, получить несколько показаний тестов и усреднить их.
    Ответ написан
    1 комментарий
  • Как узнать на каком жестком диске стоит Линукс?

    @res2001
    Developer, ex-admin
    Линукс может быть установлен на обоих дисках. Ничто не мешает монтировать разные разделы на разных дисках в разные пути, используемые системой, в т.ч. на этапе установки ОС. Тут вам не винда.
    df покажет какие разделы на каких дисках куда примонтированы.
    Так же надо посмотреть в БИОС с какого диска загружается ОС - там установлен загрузчик (скорее всего grub).

    Можете клонировать содержимое старого диска на новый и после этого заменить диски. Затем создадите на новом диске новый раздел на свободном пространстве и куда-нибудь примонтируете его. Клонировать можно из того же линукса, прицепив новый диск третьим и используя dd для побайтного клонирования.
    Ответ написан
    Комментировать
  • Как организовать одновременную работу на RDP через VPN и другой программы по удаленному доступу (Anydesk, TeamViewer, Chrome) (VNC не подходит)?

    @res2001
    Developer, ex-admin
    Вы описали сразу 2 проблемы:
    1. Десктопная винда (это та что не серверная) она однопользовательская в принципе. Т.е. работа одновременно двух пользователей - это нарушение лицензии. А подключение RDP всегда пытается создать новую пользовательскую сессию для своего подключения. Поэтому винда автоматически выкидывает пользователя, который уже залогинен.
    Можно использовать Windows Server там этой проблемы нет. Можно на десктопную винду поставить RDPWrapper, тогда поведение RDP сессии будет аналогично серверной винде, но это нарушение лицензии.
    К тому же это не избавит вас от того, что новое RDP соединение будет пытаться создать новую сессию.

    2. Есть режим RDP, когда вы подключаетесь к существующей сессии (консольной или RDP). Называется теневое подключение (Remote Desktop Shadowing). Но это требует дополнительной подготовки. Почитать можно, например, тут: https://domoticzfaq.ru/rds-shadow-tenevoye-podklyu...
    Если вы используете только теневое подключение, то с RDPWrapper можно не заморачиваться.
    Ответ написан
    3 комментария
  • Какой алгоритм быстрее и почему?

    @res2001
    Developer, ex-admin
    Ваш алгоритм быстрее. Но не лаконичнее. Это нормальное явление. Регулярно скорость достигается усложнением алгоритма. Но если раскрыть тему sort, то второй алгоритм уже не покажется таким уж простым.
    Еще ваш алгоритм не портит входные данные - часто это бывает важно.
    Ответ написан
    1 комментарий
  • Как войти на терминальный сервер без ввода логина и пароля?

    @res2001
    Developer, ex-admin
    В винде есть встроенный механизм хранения учетных данных для сетевых ресурсов: Credential Manager
    Проще всего до него добраться выполнив команду: control userpasswords2
    В открывшемся диалоге на закладке Advanced есть кнопка Manage Passwords. Вот это оно и есть.
    В общем создаете запись для удаленного сервера и пароль от нее будет использован автоматически.
    Управлять учетными данными в Credential Manager можно из командной строки с помощью утилиты cmdkey, т.е. можно автоматизировать процесс создания учеток на пользовательских компах.

    Так же в стандартном клиенте RDP после ввода пароля появляется галка "Сохранить учетные данные". Они сохраняются в тот самый Credential Manager. Затем достаточно вызвать RDP клиента и нажать Enter.
    Кроме того после полной настройки подключения в клиенте можно сохранить все настройки в *.rdp файл (кнопка "Сохранить как"), разместить его на раб.столе, например, и запускать подключение просто кликнув по иконке.
    Ответ написан
    Комментировать
  • Как правильно написать скрипт регистрации comcntr.dll при авторизации в системе?

    @res2001
    Developer, ex-admin
    Не в курсе про 1С и comcntr, но regsvr32 - регистрирует СОМ объекты.
    Чтоб dll зарегистрировалась ключ /n не нужен.
    И dll никуда не загружается. Регистрация - это внесение некоторых данных о СОМ объекте, содержащемся в dll в реестр винды. Чтобы в дальнейшем винда смогла вызывать этот объект.
    Кроме регистрации regsvr32 выполняет еще DllInstall - тут могут быть выполнены еще какие-то произвольные действия, необходимые объекту.
    Вообще я бы сначала скопировал dll на локальный диск, и только потом регистрировал уже с локального диска.
    По ключам: запустите: regsvr32 /?
    Ответ написан
  • Декларация и инициализация, в чем различия?

    @res2001
    Developer, ex-admin
    По моему, на русском чаще используют термин объявление, а не декларация. По крайней мере мне так привычнее.
    Объявление в одном из возможных переводов на английский звучит как declaration.
    https://en.cppreference.com/w/c/language/declarations
    https://en.cppreference.com/w/c/language/type

    Вы не правильно сопоставляете инициализацию и декларацию (объявление). Сопоставлять надо объявление и определение.
    Инициализация - всего лишь присвоение переменной некоторого начального значения. Она может быть при определении переменной или потом - не важно. Важно то, что перед инициализацией память для переменной должна быть выделена.
    Память выделяется когда переменная определяется.
    При объявлении память не выделяется, а только описывается (объявляется) тип. Тип включает в себя информацию о размере, выравнивании, возможных операциях, что-еще. Встроенные типы (int и т.п.) уже объявлены заранее и известны компилятору.
    Может быть предварительное объявление. Предварительных объявлений может быть сколько угодно много, если они не противоречат друг другу. Настоящее объявление может быть только одно.

    Понять различие между объявлением и определением на простом встроенном типе (int) довольно сложно, потому что сам тип уже известен, его не нужно объявлять. Для примера буду использовать структуру.

    Кроме того важно где конкретно в коде программы определена переменная - глобально (по отношению к файлу исходного кода) или локально (в функции).
    struct s;                     // предварительное объявление
    struct s { int v; };       // объявление структуры
    strcut s s1;                // определение глобальной структуры
    struct s s2 = { 0 };     // определение глобальной инициализированной структуры
    int main()
    {
      struct s s3;             // определение локальной структуры
    }

    Предварительное объявление - говорит о том, что где-то есть полное объявление. Тип объявленный только предварительным объявлением - не завершенный (не полный). Нельзя определить переменную по неполному типа. НО можно определить указатель на неполный тип. Но обращаться по указателю на неполный тип нельзя. Но присвоить адрес можно :-) Это можно использовать в своих интересах.
    После полного объявления типа уже можно определять переменные этого типа.
    s1 - глобальная не инициализированная структура. Память под нее выделяется в секции bss исполняемого файла. В исполняемом файле обычно не выделяется память непосредственно, но сохраняется размер секции. Загрузчик ОС читает размер секции из файла и выделяет память нужного размера. Глобальные не инициализированные переменные на самом деле инициализируются неявно нулем.
    s2 - глобальная инициализированная структура. Память под нее выделяется в секции data исполняемого файла. Тут уже не достаточно сохранить информацию о секции, т.к. есть начальные значения. Поэтому такие переменные непосредственно присутствуют в исполняемом файле (точнее выделена память под них и присвоено начальное значение). Есть еще секция rodata - для константных данных.
    s3 - локальная не инициализированная переменная. Память под нее выделяется на стеке. Не зависимо от того инициализирована переменная или нет, память выделена, а значит в этой памяти уже что-то лежит - не бывает "пустой" памяти. В случае не инициализированной переменной на стеке, в памяти лежит мусор, который остался тут от прошлых действий.
    Ответ написан
    1 комментарий
  • Как в одном проекте Clion создать несколько программ?

    @res2001
    Developer, ex-admin
    Я не использую CLion, но знаю что он использует cmake для проектов, а значит в нем работают механизмы cmake.
    Так что вы просто можете добавить еще одну цель в cmakelists.txt. Возможно в CLion это можно сделать как-то потыкав мышкой. Обычно cmakelists.txt правится руками. Смотрите документацию по cmake, у них довольно толковая документашка.

    Если программы как-то взаимосвязаны, то, возможно, есть смысл держать их в одном проекте. Но не обязательно.
    Если нет, то это почти наверняка плохая идея.
    Ответ написан
    Комментировать
  • Как создать указатель на вводимый текст?

    @res2001
    Developer, ex-admin
    Ну и покажите что вы пытались сделать.

    Вообще текст куда-то должен попасть после ввода. Для этого функции чтения вы должны дать буфер, куда она и запишет, все что прочитала.

    В типичной ситуации, когда не известно сколько данных будет введено, вы выделяете буфер некоторого размера (1Кб например), вызываете функцию чтения с этим буфером. Если функция полностью забила весь буфер и еще хочет - выделяете буфер большего размера, копируете содержимое предыдущего буфера, предыдущий буфер удаляете. Снова вызываете функцию чтения со смещением в новом буфере. И так пока не прочитаются все данные.
    Если же введенные данные должны быть как-то обработаны, то обычно все что прочиталось сразу обрабатывается, после обработки буфер обычно пустой (или заполнен остатками не обработанных данных, которые надо дополнить) и читаете снова в тот же буфер.

    Когда вы выделите буфер (с помощью malloc например), вы получите указатель. Пока этот указатель указывает на "пустой" буфер. После чтения в буфер, указатель будет указывать на прочтенные данные. Функция чтения вернет вам еще и длину прочитанных данных. Этого достаточно для дальнейшей работы с буфером.
    Ответ написан
    8 комментариев
  • Как сохранить значения нескольких переменных в С++ 17?

    @res2001
    Developer, ex-admin
    Вы же из getInfo возвращаете вектор, вот и принимайте вектор. В нулевом элементе вектора будет normal_weight, в первом weight. Вместо вектора можно было бы использовать std::pair или std::tuple. Они хранят свои данные статически, а вектор выделяет динамический массив, что в вашем случае максимально избыточно.

    Другой вариант передавайте в getInfo ссылки, тогда не надо будет ничего возвращать, значения в main появятся сами собой :-) Сейчас у вас аргутменты getInfo не понятно какую роль выполняют.
    Ответ написан
  • Почему не работает самоподписанный сертификат?

    @res2001
    Developer, ex-admin
    В корневые нужно пихать только сертификат ЦА. Это контейнер для них.

    Самоподписанный сертификат - это другое. Это когда у вас нет ЦА и вы просто выпускаете сертификат сервера и он сам себя подписывает. Такой простейший вариант сертификата.

    Сертификат ЦА - самоподписанный, т.к. его никто не подписывавет, но используете вы сертификат сервера и возможно клиента, а эти оба сертификата подписываются ЦА и они не самоподписанные. В работе используется сертификат ЦА только для проверки подписи предоставленного сертификата сервера и/или клиента, дальше для всего используются серверный и клиентский сертификаты.
    Не знаю особенностей Jitsi Meet, но по ссылке нет самоподписанных сертификатов. Там упор делается на использование LetsEncrypt, но по большому счету разницы нет - используете ли вы ЦА от LetsEncrypt или свой собственный. В случае своего ЦА , вы должны обеспечить возможность проверки сертификатов, правильно установив сертификат ЦА, тогда как сертификат LetsEncrypt (и других известных публичных ЦА) обычно уже установлен в системе. Процесс контроля за сроком сертификатов, их перевыпуском, ведением списка отозванных сертификатов и его доступностью то же ложится на вас.

    Любой сертификат содержит в себе публичный ключ владельца сертификата. Вторая часть ключа - секретный ключ - идет в отдельном файле. Серктеный ключ ЦА должен находится только на самом ЦА, он требуется только для выпуска новых клиентских сертификатов. В остальных случаях используется только сертификат ЦА, который можно свободно распространять. Аналогично и секретные ключи сервера/клиента - они должны находиться только у владельца ключа.
    Ответ написан
    1 комментарий
  • Как пингануть хост, находящийся за NAT, но когда при этом на шлюзе есть ssh?

    @res2001
    Developer, ex-admin
    ssh клиенты обычно позволяют подключиться и запустить команду на удаленном хосте. Подключаетесь и запускаете пинг сервера.
    Ответ написан
  • PKI. CA шифрует своим закрытым ключом или же открытом?

    @res2001
    Developer, ex-admin
    Сертификат не шифруются. Там нет секретной информации. Сертификат содержит публичный ключ и некоторые другие открытые параметры. Сертификат подписывается секретным ключом ЦА, для проверки подписи используется публичный ключ ЦА.
    ЭЦП всегда делается на секретном ключе, так что здесь нет какого-то отступления от правил.
    Ответ написан
    2 комментария
  • Почему переопределение метода без virtual -- это не переопределение?

    @res2001
    Developer, ex-admin
    Переопределить можно в любом случае, хоть с virtual, хоть без.
    Но тут важно что вам надо от переопределенного метода. Если вам нужно использовать полиморфизм, то нужно ставить virttual, если нет - то нет.

    Например дополним ваш пример функцией:
    void func(struct A &a)
    {
      a.fn();
    }
    
    int main() {
      B b;
      b.fn();
      func(b);
    }

    И передадим туда ссылку на b. Будет напечатана А, т.к. методы fn не виртуальные.
    Если были бы виртуальные, то напечатается B - полиморфизм в действии.
    Ответ написан
    Комментировать
  • Как можно передать unsigned char[] PROGMEM в функцию?

    @res2001
    Developer, ex-admin
    void func(const unsigned char *array, size_t array_length);
    ...
    func(bfr, sizeof(bfr)/sizeof(bfr[0]));


    Не знаю, что такое PROGMEM, видимо это какой-то макрос, который навешивает какой-нибудь аттрибут для типа.
    Ответ написан
    Комментировать
  • Возможно ли создание своего типа данных - массива бит?

    @res2001
    Developer, ex-admin
    В п.1 написана какая-то синтаксически не корректная хрень, смысла которой я понять не могу.

    Массив бит или битовое поле можно реализовать, конечно. Фактически это будет массив байт (или любого другого беззнакового целого), можно его спрятать в typedef и реализовать над ним несколько операций отдельными функциями.
    Например в С++ есть специализация std::vector<bool>, которая для экономии памяти использует внутри битовый массив, а не массив bool, как можно было бы подумать.

    Объявляете байт и работаете с отдельными битами с помощью битовых операций. Если есть необходимость в более широком битовом поле, то можно все унифицировать: при инициализации задаете размер битового поля, вычисляете по заданному размеру размер массива (можно использовать uint8_t, uint16_t, uint32_t или uint64_t - любой беззнаковый целочисленный тип оптимальной длинны), выделяете память для массива.
    Операции над битовым полем:
    1. создание/удаление
    2. установить/снять бит по номеру
    3. проверить установлен ли бит по номеру
    4. опционально вычисление количества установленных бит и/или проверка пустое ли битовое поле.

    Все это не трудно сделать. Можно даже заморочится и сделать на макросах универсальный вариант, где тип данных для массива будет выбираться в зависимости от размера битового поля. Не уверен, что это надо на самом деле, вполне достаточно использовать массив uint8_t для всех размеров битового поля.

    Объявить переменную размером в один бит (или размером не кратным 8 бит) нельзя, потому что в современных компьютерах минимально адресуемая единица памяти - 1 байт. Была бы 1 бит - можно было бы объявлять переменные размером в 1(2,3, 11, ...) бит. Это архитектурное ограничение компьютеров, а не языка программирования.
    Ответ написан
    2 комментария