Machen Sie die Datenbank für die entfernte Verbindung verfügbar

Zunächst einmal gibt es Fälle, in denen man eine Anwendung mit einer Datenbankverbindung erstellen muss. Das wird gemacht, um sich nicht zu sehr mit der Backend-Entwicklung aufzuhalten und sich aufgrund von fehlenden Ressourcen und Fähigkeiten auf das Frontend zu konzentrieren. Ich behaupte nicht, dass meine Lösung sicher ist, aber sie funktioniert.

Da ich nicht gerne für Hostingbezahle, habe ich das Netzwerk an meinem Arbeitsplatz genutzt, dort gibt es eine öffentliche IP. Hier ist die Struktur:

Machen Sie die Datenbank für die entfernte Verbindung verfügbar

Ich habe Zugriff auf mehrere Computer, genauer gesagt auf 192.168.1.2 (auch 192.168.0.2), dort läuft Linux, und auf 192.168.0.3 mit Windows. Insgesamt habe ich für meine Anwendung MySQL gewählt und geschaut, was es auf Linux gibt. Dort war es bereits installiert, aber das Passwort wusste niemand, und diejenigen, die es wussten, hatten es vergessen (die, die vor mir gearbeitet haben). Als ich herausfand, dass es niemandem mehr nützte, habe ich es gelöscht und versucht, es neu zu installieren. Der Speicher war nicht ausreichend, und da ich dafür einen Monitor, eine Tastatur und eine Maus anschließen müsste, beschloss ich, dieses Vorhaben aufzugeben. Zumal der Windows-Rechner viel leistungsstärker ist und ich außerdem einen eigenen Laptop dazu habe. Die Installation selbst werde ich nicht beschreiben, es gibt jede Menge Manuals und Videos darüber. Nachdem ich MySQL auf dem Windows-Rechner installiert hatte, wollte ich ein Backup der Tabellen vom Laptop auf die Arbeitsstation machen.

Das geschieht so (in meinem Fall):

mysqldump -uroot -p your_base > dump_file.sql

Dann erstellen wir in der neuen Datenbank eine Datenbank und stellen das Backup auf der „neuen“ Maschine wieder her.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Die Backup-Datei muss auf die neue Maschine kopiert werden, und wenn sie sich möglicherweise nicht im Verzeichnis mit dem Dienstprogramm befindet, muss der vollständige Pfad angegeben werden. (Ich habe das Backup einfach auf GitHub hochgeladen und es auf die neue Maschine geklont). Ich würde gerne zeigen, wie die Tabellen erstellt werden, aber ich habe die Screenshots nicht gespeichert, und ich denke, das ist auch für einen Studenten im 2. oder 3. Jahr nicht schwierig.

Nachdem ich alle Tabellen wiederhergestellt hatte, war es an der Zeit, den Remote-Zugriff auf die DB verfügbar zu machen. Insgesamt führten solche Befehle nicht zum Erfolg (gaben nur Lesezugriff auf select).

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

Genauer gesagt, ich konnte mich nur mit dem Befehl verbinden,

mysql -h localhost -u client -pclient

aber mit diesem konnte ich mich nicht verbinden.

mysql -h 192.168.0.3 -u client -pclient

Dazu konnte ich mich auch nicht über diese Adresse und von root aus verbinden.

Das Programm MySQL Workbench hat mir geholfen, die Einstellungen zu ändern, von localhost auf %, und es funktioniert, obwohl das beim Client nicht geholfen hat. Jetzt können Sie sich von der Konsole oder aus dem Code von jeder Adresse mit der Datenbank verbinden.

Machen Sie die Datenbank für die entfernte Verbindung verfügbar

Außerdem müssen Sie das Netzwerk in ein Heim- oder Firmennetzwerk einrichten und die Windows-Firewall deaktivieren, sonst können Sie nicht einmal ein Ping auf diese Maschine durchführen (geschweige denn sich mit der Datenbank verbinden).

Die halbe Arbeit ist erledigt, jetzt muss ich von zu Hause aus auf die Datenbank zugreifen können.

Wie aus dem Netzwerkschema ersichtlich, müssen wir den Weg vom 192.168.0.3 zum 192.168.1.1 (Router) zurückverfolgen. Lassen Sie uns den Weg von 192.168.1.1 zu 192.168.1.2 so einrichten:

Machen Sie die Datenbank für die entfernte Verbindung verfügbar

Im Großen und Ganzen zeigt das Bild nichts an – ich schreibe es von Hand:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Das kann nur im selben Subnetz gemacht werden, das heißt, man kann nicht direkt auf die Adresse 192.168.0.2 oder 192.168.0.3 weiterleiten.

Das ist notwendig, damit der Router weiß, wo sich das Subnetz 192.168.0.0/24 befindet (lernen Sie die Grundlagen der Netzwerke, das ist nützlich).

Jetzt fügen wir die Portweiterleitung für 3306 hinzu (der Standardport für MySQL, es sei denn, Sie haben ihn bei der Installation geändert) auf die Adresse 192.168.1.2.

Machen Sie die Datenbank für die entfernte Verbindung verfügbar

Übrig bleibt die schwierigste Aufgabe, die Weiterleitung auf der Linux-Maschine einzurichten (sie hat zwei Netzwerkkarten: 192.168.1.2 (Schnittstelle enp3s1) und 192.168.0.2 (Schnittstelle enp3s0), damit die Netzwerkkarten wissen, dass sie von 192.168.1.2 auf 192.168.0.2 weitergeleitet werden müssen, und dann zu unserem Windows-Rechner mit 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
und die letzte Zeile speichert die eingegebenen Befehle, damit sie beim Neustart des Systems nicht verloren gehen
sudo service iptables-persistent save

Das heißt, die erste Zeile bedeutet, dass wir die erste Verbindung akzeptieren, die zweite und dritte, dass Pakete in beide Richtungen erlaubt sind, die vierte und fünfte bedeuten die Ersetzung von Ziel- und Quelladresse. Und voilà, jetzt kann man von zu Hause aus über MySQL verbinden. Und schließlich mein C++-Code, der das erledigt:

//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); //Если используется оконное приложение
	}
	// Подключаемся к zu einem Server
	if (!mysql_real_connect(conn, "192.168.0.3", "root", "password", "your_base", NULL, NULL, 0))
	{
		// Wenn keine Verbindung hergestellt werden kann mit Server 
		// базы данных выводим сообщение об ошибке
		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;
};

Jetzt kann ich dieses Programm bedenkenlos an jeden weitergeben, und es muss nicht umgeschrieben werden, damit es lokal funktioniert.

Quelle: habr.com

60GB SSD 8Gb DDR4