Menjadikan pangkalan data tersedia untuk sambungan jauh

Mari kita mulakan dengan fakta bahawa ada kalanya anda perlu membuat aplikasi dengan sambungan pangkalan data. Ini dilakukan agar tidak terlalu mendalami pembangunan bahagian belakang dan menumpukan perhatian pada bahagian hadapan kerana kekurangan tangan dan kemahiran. Saya tidak akan mengatakan bahawa penyelesaian saya akan selamat, tetapi ia berfungsi.

Oleh kerana saya tidak suka membayar untuk hosting, saya menggunakan rangkaian di tempat kerja saya, ada IP putih. Berikut adalah strukturnya:

Menjadikan pangkalan data tersedia untuk sambungan jauh

Saya mempunyai akses kepada beberapa komputer, lebih tepat lagi kepada 192.168.1.2 (aka 192.168.0.2) terdapat Linux dan 192.168.0.3 dengan Windows. Secara umum, untuk aplikasi saya, saya memilih mysql dan melihat apa yang ada di Linux. Ia telah dipasang di sana, tetapi tiada siapa yang tahu kata laluan, dan mereka yang tahu terlupa (mereka yang bekerja sebelum saya). Selepas mengetahui bahawa tiada siapa yang memerlukannya, saya memadamkannya dan cuba memasangnya semula. Ingatan tidak mencukupi, dan kerana untuk membetulkan ralat ini, saya perlu menyambungkan monitor dan papan kekunci dengan tetikus padanya, saya memutuskan untuk berhenti daripada perniagaan ini. Lebih-lebih lagi, mesin Windows jauh lebih berkuasa, dan ditambah dengan segala-galanya, saya sendiri mempunyainya pada komputer riba saya di rumah. Pada dasarnya, saya tidak akan menerangkan pemasangan itu sendiri, terdapat banyak manual dan video mengenainya. Setelah memasang mysql pada mesin Windows, saya memutuskan untuk membuat sandaran jadual dari komputer riba ke stesen kerja.

Ia dilakukan seperti ini (dalam kes saya):

mysqldump -uroot -p your_base > dump_file.sql

Seterusnya, kami mencipta pangkalan data dalam pangkalan data baharu dan memulihkan sandaran pada mesin "baru".

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Fail dengan sandaran mesti diletakkan pada mesin baru, dan jika tidak dalam direktori dengan utiliti, maka laluan penuh ke sana adalah mungkin. (Saya baru sahaja memuat naik sandaran ke github dan mengklonkannya ke mesin baharu). Saya akan menambah cara jadual itu sendiri dicipta, tetapi saya tidak menyimpan tangkapan skrin, dan saya fikir ia tidak sukar walaupun untuk pelajar 2-3 tahun.

Apabila saya memulihkan semua jadual, sudah tiba masanya untuk menyediakan akses jauh ke pangkalan data. Secara umum, arahan sedemikian tidak membawa kepada kejayaan (hanya diberi hak untuk membaca pilih)

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

Lebih tepat lagi, saya hanya boleh menyambung ke pangkalan data dengan arahan,

mysql -h localhost -u client -pclient

dan yang ini tidak boleh

mysql -h 192.168.0.3 -u client -pclient

Ia tidak sesuai dengan saya, saya juga tidak dapat menyambung melalui alamat ini sebagai root.

Program meja kerja mysql membantu, di sana dalam tetapan anda menukar localhost kepada% dan ia berfungsi, walaupun pelanggan tidak membantu. Kini anda boleh menyambung ke pangkalan data dari konsol atau dari kod dari mana-mana alamat.

Menjadikan pangkalan data tersedia untuk sambungan jauh

Anda juga perlu membuat rangkaian rumah atau perusahaan dan mematikan tembok api Windows, jika tidak, anda tidak akan dapat ping mesin ini (bukannya ia akan menyambung ke pangkalan data).

Separuh daripada kerja selesai, maka saya perlu dapat menyambung ke pangkalan data dari rumah.

Seperti yang anda lihat dari rajah rangkaian, anda perlu pergi ke Internet dari 192.168.0.3 hingga 192.168.1.1 (penghala), mari pergi ke arah yang bertentangan. Mari kita sediakan laluan dari 192.168.1.1 hingga 192.168.1.2 seperti ini:

Menjadikan pangkalan data tersedia untuk sambungan jauh

Secara umum, gambar tidak ditunjukkan - Saya akan menulis dengan tangan saya:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Ini hanya boleh dilakukan dalam satu subnet, iaitu, anda tidak boleh memajukan segera ke alamat 192.168.0.2 atau 192.168.0.3

Ini adalah perlu supaya penghala mengetahui di mana subnet 192.168.0.0/24 berada (ketahui asas rangkaian berguna).

Sekarang kami menambah port forwarding 3306 (port mysql secara lalai (jika anda tidak menukarnya semasa pemasangan)) ke alamat 192.168.1.2

Menjadikan pangkalan data tersedia untuk sambungan jauh

Sekarang perkara yang paling sukar untuk dilakukan ialah melakukan pemajuan pada mesin Linux (ia mempunyai dua kad rangkaian 192.168.1.2 (antara muka enp3s1) dan 192.168.0.2 (antara muka enp3s0) supaya kad rangkaian tahu apa yang hendak dipindahkan dari 192.168.1.2 ke 192.168.0.2, dan kemudian ke mesin Windows kami dengan 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

Itu. Baris pertama bermakna kami menerima sambungan pertama, ke-1 dan ke-2 bahawa adalah mungkin untuk menghantar paket dalam kedua-dua arah, ke-3 dan ke-4 bermaksud penggantian alamat destinasi dan sumber. Dan voila, anda boleh menyambung dari rumah melalui mysql. Dan akhirnya, kod C++ saya yang melakukan ini:

//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;
};

Kini anda boleh membuang program ini dengan selamat kepada sesiapa sahaja dan anda tidak perlu menulis semula supaya ia berfungsi secara tempatan.

Sumber: www.habr.com

Tambah komen