Punerea la dispoziție a bazei de date pentru conexiunea de la distanță

Să începem cu faptul că există cazuri când trebuie să faci o aplicație cu conexiune la o bază de date. Acest lucru se face pentru a nu aprofunda prea mult în dezvoltarea backend și pentru a vă concentra pe frontend din cauza lipsei de mâini și abilități. Nu pot spune că soluția mea va fi sigură, dar funcționează.

Deoarece nu-mi place să plătesc pentru găzduire, am folosit rețeaua la locul meu de muncă, acolo există un IP alb. Iată structura sa:

Punerea la dispoziție a bazei de date pentru conexiunea de la distanță

Am acces la mai multe computere, mai exact 192.168.1.2 (aka 192.168.0.2) cu Linux instalat acolo și 192.168.0.3 cu Windows. În general, am ales mysql pentru aplicația mea și m-am uitat la ce era disponibil pe Linux. Era deja instalat acolo, dar nimeni nu știe parola, iar cei care știau au uitat (cei care au lucrat înaintea mea). După ce am aflat că nimeni nu are nevoie de el, l-am șters și am încercat să îl instalez din nou. Nu era suficientă memorie și, deoarece pentru a remedia această eroare ar trebui să conectez la ea un monitor și o tastatură cu un mouse, am decis să renunț la această chestiune. Mai mult, mașina cu Windows este mult mai puternică și în plus, o am pe laptop acasă. În principiu, nu voi descrie instalarea în sine; există o mulțime de manuale și videoclipuri despre aceasta. După ce am instalat mysql pe o mașină Windows, am decis să fac backup pentru tabelele de pe laptop pe stația mea de lucru.

Se face asa (in cazul meu):

mysqldump -uroot -p your_base > dump_file.sql

Apoi, creăm o bază de date în noua bază de date și restaurăm copia de rezervă 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 de rezervă trebuie plasat pe noua mașină și, poate, dacă nu în directorul cu utilitarul, atunci calea completă către acesta. (Tocmai am încărcat copia de rezervă în GitHub și l-am clonat pe o mașină nouă). Aș adăuga cum sunt create tabelele în sine, dar nu am salvat capturile de ecran și cred că nu este dificil nici măcar pentru un student de 2-3 ani.

Când toate tabelele au fost restaurate, este timpul să faceți disponibil accesul de la distanță la baza de date. În general, astfel de comenzi nu au condus la succes (a dat doar permisiunea de citire pentru a selecta)

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

Mai exact, m-am putut conecta la baza de date doar cu comanda,

mysql -h localhost -u client -pclient

dar acesta nu mai putea

mysql -h 192.168.0.3 -u client -pclient

Acest lucru nu a funcționat pentru mine și nu m-am putut conecta prin această adresă ca root.

Programul mysql workbench a ajutat; în setări, schimbați localhost în % și funcționează, deși clientul nu a ajutat. Acum te poți conecta la baza de date din consolă sau din cod de la orice adresă.

Punerea la dispoziție a bazei de date pentru conexiunea de la distanță

De asemenea, trebuie să faceți o rețea de acasă sau de afaceri și să dezactivați paravanul de protecție Windows, altfel nu veți putea nici măcar să faceți ping la această mașină (darămite să vă conectați la baza de date).

Jumătate din treabă este gata, acum trebuie să mă pot conecta la baza de date de acasă.

După cum puteți vedea din diagrama rețelei, pentru a ajunge la Internet trebuie să treceți de la 192.168.0.3 la 192.168.1.1 (router), să mergem în direcția opusă. Să configuram ruta de la 192.168.1.1 la 192.168.1.2 astfel:

Punerea la dispoziție a bazei de date pentru conexiunea de la distanță

În general, imaginea nu apare, așa că o voi scrie de mână:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Acest lucru se poate face doar într-o singură subrețea, adică nu puteți redirecționa imediat la adresa 192.168.0.2 sau 192.168.0.3

Acest lucru este necesar pentru ca routerul să știe unde se află subrețeaua 192.168.0.0/24 (învățarea elementelor de bază ale rețelelor este utilă).

Acum adăugăm port forwarding 3306 (portul implicit mysql (dacă nu l-ați schimbat în timpul instalării)) la adresa 192.168.1.2

Punerea la dispoziție a bazei de date pentru conexiunea de la distanță

Cel mai dificil lucru rămas de făcut este să faci redirecționare pe o mașină Linux (are două plăci de rețea 192.168.1.2 (interfață enp3s1) și 192.168.0.2 (interfață enp3s0) pentru ca plăcile de rețea să știe ce să le transfere de la 192.168.1.2 la 192.168.0.2 și apoi la mașina noastră 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
и последняя строчка сохраняет введенные команды чтобы они при перезапуске оси не стерлись
sudo service iptables-persistent save

Acestea. Prima linie înseamnă că acceptăm prima conexiune, a 1-a și a 2-a că putem trimite pachete în ambele direcții, a 3-a și a 4-a înseamnă schimbarea adreselor de destinație și sursă. Și voila, vă puteți conecta de acasă prin mysql. Și, în sfârșit, codul meu 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); //Если используется оконное приложение
	}
	// Подключаемся к серверу
	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;
};

Acum puteți trimite în siguranță acest program oricui și nu trebuie să-l rescrieți pentru a-l face să funcționeze local.

Sursa: www.habr.com

Adauga un comentariu