Почнемо з того, що бувають випадки, коли потрібно робити додаток з підключенням до бази даних. Це робиться для того, щоб особливо не копатися в розробці бекенд і сконцентруватися на фронтенді через брак рук і навичок. Я не беруся казати, що моє рішення буде безпечним, але воно працює.
Оскільки я не люблю платити за хостинг, я скористався мережею на роботі, там є білий IP. Ось її структура:
У мене є доступ до кількох комп'ютерів, точніше до 192.168.1.2 (він же 192.168.0.2) там стоїть Linux і до 192.168.0.3 з Windows. Загалом, для своєї програми я вибрав mysql і подивився що є на Linux. Там уже було встановлено він, але пароль ніхто не знає, а ті, хто знали забули (ті, хто працював до мене). Дізнавшись, що він нікому не потрібен, я його видалив і спробував встановити заново. Пам'ять не вистачало і оскільки, щоб виправити цю помилку, довелося б підключати до нього монітор і клавіатуру з мишею, я вирішив кинути цю справу. Тим більше що машина з Windows куди потужніша і плюс до всього у мене у самого стоїть вона на домашньому ноутбуку. В принципі саму установку я описувати не буду, є купа мануалів та відео про це. Встановивши MySQL на Windows машину, я вирішив зробити бекап таблиць з ноутбука на робочу станцію.
Робиться це так (у моєму випадку):
mysqldump -uroot -p your_base > dump_file.sql
Далі у новій базі даних створюємо базу даних та відновлюємо бекап на «новій» машині.
mysql -h localhost -u root -p
create database your_base;
use your_base;
mysql -uroot -p your_base < dump_file.sql
show tables;
Файл з бекапом треба на нову машину покласти і можливо якщо не в директорії з утилітою, то повний шлях до неї. (Я просто залив бекап на гітхаб і клонував його на нову машину). Я додав би як створюються самі таблиці, але не зберіг скрини, та й думаю це не складно навіть студенту 2-3 курсу.
Коли відновив усі таблиці, настав час зробити доступним віддалений доступ до бд. Загалом такі команди до успіху не привели (видав тільки право на читання select).
create user 'client'@'%' IDENTIFIED by 'client';
grant select on your_base . * to 'client'@'%';
flush privileges;
Точніше я міг підключитися до бази тільки командою,
mysql -h localhost -u client -pclient
а такий уже не міг
mysql -h 192.168.0.3 -u client -pclient
мені це не підходило також не могло підключитися через цю адресу та від root.
Допомогла програма mysql workbench там у налаштуваннях змінюєте localhost на % і працює, хоча client це не допомогло. Тепер ви можете підключатися до бд з консолі або коду з будь-якої адреси.
Ще потрібно зробити домашню мережу або підприємства і вимкнути брандмауер Windows інакше не зможете навіть зробити пінг цієї машини (не те щоб підключитися до бд).
Підлога справи зроблено, далі потрібно, щоб я міг з дому підключитися до бази даних.
Як видно із схеми мережі, то до інтернету треба пройти шлях від 192.168.0.3 до 192.168.1.1 (роутер) підемо у зворотний бік. Налаштуємо маршрут від 192.168.1.1 до 192.168.1.2 таким чином:
Загалом картинку не показує — напишу руками:
route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2
Це можна зробити тільки в одній підмережі, тобто не можна відразу прокинути на адресу 192.168.0.2 або 192.168.0.3
Це потрібно, щоб роутер знав де знаходиться підсіти 192.168.0.0/24 (вчіть основи мереж це корисно).
Тепер додаємо прокидання порту 3306 (порт mysql по дефолту (якщо ви його при установки тільки не змінили)) на адресу 192.168.1.2
Ось залишилося зробити найскладніше це зробити форвардинг на лінукс машині (на ній дві мережеві картки 192.168.1.2 (інтерфейс enp3s1) і 192.168.0.2 (інтерфейс enp3s0) щоб мережевики знали, що перекинути їх з 192.168.1.2. нашу машину Windows з MySql.
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -p tcp --syn --dport 3306 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A FORWARD -i enp3s1 -o enp3s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i enp3s0 -o enp3s1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t nat -A PREROUTING -i enp3s1 -p tcp --dport 3306 -j DNAT --to-destination 192.168.0.3
sudo iptables -t nat -A POSTROUTING -o enp3s0 -p tcp --dport 3306 -d 192.168.0.3 -j SNAT --to-source 192.168.1.2
и последняя строчка сохраняет введенные команды чтобы они при перезапуске оси не стерлись
sudo service iptables-persistent save
Тобто. 1-я рядок означає, що ми приймаємо перше з'єднання, 2-а і 3-я що можна в обидві сторони пускати пакети, 4-я і 5-я означає заміну адреси призначення та джерела. І вуаля можна коннектіться з дому через mysql. І насамкінець мій код на с++ який це робить:
//DataBaseConnection.cpp
#include "DataBaseConnection.h"
DataBaseConnection::DataBaseConnection()
{
}
void DataBaseConnection::Connect()
{
// Получаем дескриптор соединения
conn = mysql_init(NULL);
if (conn == NULL)
{
// Если дескриптор не получен – выводим сообщение об ошибке
fprintf(stderr, "Error: can'tcreate MySQL-descriptorn");
//exit(1); //Если используется оконное приложение
}
// Подключаемся к серверу
if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
{
// Если нет возможности установить соединение с сервером
// базы данных выводим сообщение об ошибке
fprintf(stderr, "Error: can't connect to database: %sn", mysql_error(conn));
}
else
{
// Если соединение успешно установлено выводим фразу - "Success!"
fprintf(stdout, "Success!n");
}
}
std::vector<std::string> DataBaseConnection::Query()
{
vectordrum.clear();
std::string query = "SELECT * FROM drum where id=0";
const char * q = query.c_str();
qstate = mysql_query(conn, q);
if (!qstate)
{
res = mysql_store_result(conn);
while (row = mysql_fetch_row(res))
{
//printf("ID: %s,Position: %s, Image: %sn", row[0], row[1], row[2]);
vectordrum.push_back(row[2]);
}
}
else
{
std::cout << "Query failed:" << mysql_error(conn) << std::endl;
}
return vectordrum;
}
void DataBaseConnection::Close()
{
// Закрываем соединение с сервером базы данных
mysql_close(conn);
}
DataBaseConnection::~DataBaseConnection()
{
vectordrum.clear();
}
//DataBaseConnection.h
#pragma once
#include <iostream>
#include <mysql.h>
#include <vector>
#pragma comment(lib,"mysqlcppconn.lib")
#pragma comment(lib,"libmysql.lib")
class DataBaseConnection
{
public:
DataBaseConnection();
void Connect();
std::vector<std::string> Query();
void Close();
~DataBaseConnection();
MYSQL *conn;
MYSQL_ROW row;
MYSQL_RES *res;
int qstate;
std::vector<std::string> vectordrum;
};
Тепер можна сміливо скидати цю програму будь-кому, і не треба переписувати щоб вона працювала локально.
Джерело: habr.com