Нека започнем с това, че има случаи, когато е необходимо да се създаде приложение с връзка към база данни. Това се прави, за да не се задълбочаваме в бекенд разработката и да се фокусираме върху фронтенда заради недостиг на ръце и умения. Не искам да твърдя, че моето решение ще бъде безопасно, но то работи.
Тъй като не обичам да плащам за хостинг, използвах мрежата на работа, където имам бял 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
След това в новата база данни създаваме база danych и възстановяваме резервното копие на 'новата' машина.
mysql -h localhost -u root -p
create database your_base;
use your_base;
mysql -uroot -p your_base < dump_file.sql
show tables;
Файлът с резервното копие трябва да бъде поставен на новата машина и ако не е в директорията с утилитата, тогава пълния път до него. (Аз просто качих резервното копие в github и го клонирах на новата машина). Бих добавил как се създават самите таблици, но не запазих снимките и мисля, че това не е сложно дори за студент от 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 на % и всичко работи, въпреки че на клиента това не помогна. Сега можете да се свържете с базата данни от конзолата или от кода от всеки адрес.

Трябва също да настроите мрежата като домашна или бизнес и да изключите Windows Firewall, иначе дори не можете да пингнете тази машина (да не говорим за свързване с базата данни).
Полувината работа е свършена, сега трябва да мога да се свържа с базата данни от дома.
Както се вижда от схемата на мрежата, трябва да прекараме път от 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.

Остана да направим най-сложната част — пренасочването на Linux машината (на нея има две мрежови карти 192.168.1.2 (интерфейс enp3s1) и 192.168.0.2 (интерфейс enp3s0), за да знаят мрежовите карти какво да пренасочат от 192.168.1.2 на 192.168.0.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
Тоест, първият ред означава, че приемаме първото свързване, вторият и третият ред позволяват пакети да минават в двете посоки, четвъртият и петият означават замяната на целевия и източника адрес. И хоп, можете да се свържете от дома си чрез mysql. И накрая, моят код на C++ който прави това:
//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
