Facem disponibilă baza de date pentru conectarea la distanță

Să începem prin a spune că există situații când trebuie să construiești o aplicație cu conectare la baza de date. Acest lucru se face pentru a nu te concentra foarte mult pe dezvoltarea backend-ului și pentru a te axezi pe frontend din cauza lipsei de resurse și abilități. Nu pretind că soluția mea este sigură, dar funcționează.

Deoarece nu îmi place să plătesc pentru hosting, am folosit rețeaua de la locul de muncă, unde există un IP public. Iată structura acesteia:

Facem disponibilă baza de date pentru conectarea la distanță

Am acces la mai multe computere, mai exact la 192.168.1.2 (care este și 192.168.0.2) unde rulează Linux și la 192.168.0.3 cu Windows. În esență, pentru aplicația mea am ales mysql și am verificat ce este pe Linux. Acesta era deja instalat, dar nimeni nu știa parola, iar cei care știau au uitat-o (cei care au lucrat înainte de mine). Aflând că nu îi folosește nimănui, l-am șters și am încercat să-l reinstalez. Memoria nu era suficientă, iar pentru a corecta această eroare ar fi trebuit să conectez un monitor, o tastatură și un mouse, așa că am decis să renunț. În plus, mașina cu Windows este mult mai puternică și, pe deasupra, am instalat-o și eu pe laptopul acasă. Nu voi descrie instalarea în sine, există o mulțime de manuale și videoclipuri despre asta. După ce am instalat mysql pe mașina cu Windows, am decis să fac un backup al tabelelor de pe laptop pe stația de lucru.

Acest lucru se face astfel (în cazul meu):

mysqldump -uroot -p your_base > dump_file.sql

Apoi, în noua bază de date, creăm baza de date și restaurăm backup-ul pe „noua” mașină.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Fișierul cu backup-ul trebuie să fie pe noua mașină, și, dacă nu este în directorul utilitarului, atunci calea completă către el. (Eu am urcat backup-ul pe GitHub și l-am clonat pe noua mașină). Aș adăuga cum se creează tabelele însă nu am păstrat capturi de ecran și cred că nu este complicat nici pentru un student din anul 2-3.

Odată ce am restaurat toate tabelele, a venit momentul să fac accesibil accesul la baza de date de la distanță. În general, aceste comenzi nu au dus la succes (au oferit doar dreptul de citire select)

create user 'client'@'%' IDENTIFIED by 'client';
grant select on your_base . * to 'client'@'%';
flush privileges;

Mai exact, am putut să mă conectez la baza de date doar cu comanda,

mysql -h localhost -u client -pclient

dar această comandă nu a funcționat

mysql -h 192.168.0.3 -u client -pclient

acest lucru nu era potrivit pentru mine, de asemenea nu am putut să mă conectez prin această adresă nici de la root.

Programul mysql workbench m-a ajutat, acolo în setări schimbi localhost cu % și funcționează, deși clientul nu a fost de ajutor. Acum poți să te conectezi la baza de date din consolă sau din cod de pe orice adresă.

Facem disponibilă baza de date pentru conectarea la distanță

De asemenea, trebuie să configurezi rețeaua de acasă sau de la birou și să dezactivezi firewall-ul Windows, altfel nu vei putea nici măcar să faci ping la această mașină (ce să mai spunem despre conectarea la baza de date).

O mare parte din muncă este făcută, acum trebuie să pot să mă conectez la baza de date de acasă.

După cum se vede în schema rețelei, este necesar să trecem pe calea de la 192.168.0.3 la 192.168.1.1 (router), astfel că ne vom întoarce. Vom seta ruta de la 192.168.1.1 la 192.168.1.2 în felul următor:

Facem disponibilă baza de date pentru conectarea la distanță

În general, nu arată imaginea — o voi scrie manual:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Aceasta se poate face doar într-o singură subrețea, adică nu poți să redirecționezi direct la adresa 192.168.0.2 sau 192.168.0.3.

Este necesar ca routerul să știe unde se află subrețeaua 192.168.0.0/24 (învață lucrurile de bază despre rețele, este util).

Acum adăugăm redirecționarea portului 3306 (portul mysql implicit (dacă nu l-ai schimbat în timpul instalării)) la adresa 192.168.1.2.

Facem disponibilă baza de date pentru conectarea la distanță

Rămâne să facem cel mai complicat lucru, să realizăm forwarding-ul pe mașina Linux (aceasta are două plăci de rețea: 192.168.1.2 (interfața enp3s1) și 192.168.0.2 (interfața enp3s0), pentru ca plăcile de rețea să știe că trebuie să redirecționeze pachetele de la 192.168.1.2 la 192.168.0.2, apoi pe mașina Windows cu 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
ultima linie salvează comenzile introduse pentru a nu fi șterse la repornirea sistemului
sudo service iptables-persistent save

Așadar, prima linie înseamnă că acceptăm prima conexiune, liniile 2 și 3 permit pachetelor să circule în ambele direcții, linii 4 și 5 indică înlocuirea adresei de destinație și a celei sursă. Și iată, poate fi efectuată conexiunea de acasă prin mysql. Și, în final, codul meu în C++ care face asta:

//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); //Если используется оконное приложение
	}
	// Подключаемся к server
	if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
	{
		// Dacă nu este posibil să se stabilească o conexiune cu serverul 
		// базы данных выводим сообщение об ошибке
		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;
};

Acum pot distribui această aplicație oricui, fără a fi nevoie să o rescriu pentru a funcționa local.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster