91
: Январь 31, 2024, 11:10
|
Автор m_ax - Последний ответ от ssoft
|
И еще момент, лучше разделять запросы по ';' не смотря на 'SELECT'. В SQL есть и другие команды, кроме выборки данных (SELECT). По хорошему да.., но ';' не обязателен в конце запроса. Поэтому про пример трафика и пишу. Если явных признаков начала и конца нет, то парсер придется писать)).
|
92
: Январь 31, 2024, 11:00
|
Автор m_ax - Последний ответ от Old
|
И еще момент, лучше разделять запросы по ';' не смотря на 'SELECT'. В SQL есть и другие команды, кроме выборки данных (SELECT).
|
93
: Январь 31, 2024, 10:58
|
Автор m_ax - Последний ответ от ssoft
|
При подключении нового клиента, выполняем подключение к серверу и после этого имеем пару сокетов client-proxy и proxy-server, вот все что приходит по первому сокету, нужно отправить во второй и наоборот. Если один из сокетов закрывается, то нужно закрыть и второй. Как правило эти два сокета хранятся в объектах, которые называют session. Я тоже к такой схеме пришёл). Назвал объект только proxy_client. Как мне узнать, что ответ получен не полностью и ожидается продолжение?
Нужно реальный трафик смотреть. В общем случае никак. Если в сети текст, то надеяться, что есть разделитель ";", либо по слову "SELECT" или другим косвенным признакам. Если бинарный протокол, то его нужно знать, скорее всего, где-то длина пакета должна быть.
|
94
: Январь 31, 2024, 10:55
|
Автор m_ax - Последний ответ от m_ax
|
Прочитал очередную порцию данный (chunk) добавил к общему буферу. А дальше уже смотришь, если в общем буфере получена команда полностью (от SELECT и до ';'), то выкусываем ее из буфера и обрабатываем, иначе ждем оочередной чанк.
никак - tcp потоковый протокол для этих целей делают логический пакет "[размер][данные]"
Понятно) Спасибо) сегодня будет чем заняться)
|
95
: Январь 31, 2024, 10:50
|
Автор m_ax - Последний ответ от qate
|
Как мне узнать, что ответ получен не полностью и ожидается продолжение?
никак - tcp потоковый протокол для этих целей делают логический пакет "[размер][данные]"
|
96
: Январь 31, 2024, 10:49
|
Автор m_ax - Последний ответ от Old
|
Прочитал очередную порцию данный (chunk) добавил к общему буферу. А дальше уже смотришь, если в общем буфере получена команда полностью (от SELECT и до ';'), то выкусываем ее из буфера и обрабатываем, иначе ждем оочередной чанк.
|
97
: Январь 31, 2024, 10:41
|
Автор m_ax - Последний ответ от m_ax
|
А если запрос получен не полностью? Например, получили только "SELECT * FRO" а остаток прилетит позже?
Значит нужен какой то признак того, что данные полученны не полностью/полностью.. Я читаю данные в буфер C++ (Qt) char buffer[buff_size]; memset(buffer, 0, buff_size); int rc = recv(m_fds[i].fd, buffer, buff_size - 1, 0);
Как мне узнать, что ответ получен не полностью и ожидается продолжение?
|
99
: Январь 31, 2024, 10:26
|
Автор m_ax - Последний ответ от Old
|
А если запрос получен не полностью? Например, получили только "SELECT * FRO" а остаток прилетит позже?
|
100
: Январь 31, 2024, 09:51
|
Автор m_ax - Последний ответ от m_ax
|
Дожидается ответа и шлёт ответ клиенту
теперь ясно ) а как решается проблема, что трафик между клиентом, например psql, и сервером - это не plain text и вычленить sql запросы не очевидно как ? Я пока предполагаю, что это просто plain text в котором могут быть sql запросы. Сейчас реализовано так: C++ (Qt) proxy.run(std::cout, [&](const std::string & data) { auto query_list = sandbox::get_sql_query(data); for (const auto & query : query_list) out << query << std::endl; });
где парсер просто извлекает из текста запросы: C++ (Qt) #ifndef SQL_PARSER_H #define SQL_PARSER_H #include <regex> #include <string> #include <list> namespace sandbox { inline std::list<std::string> get_sql_query(const std::string & src) { std::regex query_regex("(SELECT[^;]+;)"); auto query_begin = std::sregex_iterator(src.begin(), src.end(), query_regex); auto query_end = std::sregex_iterator(); std::regex r("\\n"); std::list<std::string> result; for (std::sregex_iterator i = query_begin; i != query_end; ++i) { std::smatch match = *i; result.push_back(std::regex_replace(match.str(), r, " ")); } return result; } } /* namespace sandbox */ #endif // SQL_PARSER_H
|
|