Veritabanını uzaktan bağlantı için kullanılabilir hale getirme

Veritabanına bağlı bir uygulama yapmanız gereken durumların olduğu gerçeğiyle başlayalım. Bu, arka uç geliştirmeye çok fazla dalmamak ve el ve beceri eksikliği nedeniyle ön uç üzerinde yoğunlaşmak için yapılır. Çözümümün güvenli olacağını söyleyemem ama işe yarıyor.

Hosting için ödeme yapmayı sevmediğim için ağı iş yerimde kullandım, orada beyaz bir IP var. İşte yapısı:

Veritabanını uzaktan bağlantı için kullanılabilir hale getirme

Birkaç bilgisayara erişimim var, daha doğrusu Linux yüklü 192.168.1.2 (aka 192.168.0.2) ve Windows yüklü 192.168.0.3. Genel olarak uygulamam için MySQL'i seçtim ve Linux'ta nelerin mevcut olduğuna baktım. Zaten orada kuruluydu ama kimse şifreyi bilmiyor, bilenler de unuttu (benden önce çalışanlar). Kimsenin buna ihtiyacı olmadığını öğrendikten sonra sildim ve tekrar yüklemeyi denedim. Yeterli bellek yoktu ve bu hatayı düzeltmek için fareli bir monitör ve klavye bağlamam gerekeceğinden, bu konudan vazgeçmeye karar verdim. Üstelik Windows'lu makine çok daha güçlü ve üstelik evdeki dizüstü bilgisayarımda da var. Prensip olarak kurulumun kendisini anlatmayacağım, bununla ilgili birçok kılavuz ve video var. MySQL'i bir Windows makinesine yükledikten sonra, tabloları dizüstü bilgisayarımdan iş istasyonuma yedeklemeye karar verdim.

Bu şekilde yapılır (benim durumumda):

mysqldump -uroot -p your_base > dump_file.sql

Daha sonra yeni veritabanında bir veritabanı oluşturup yedeği “yeni” makineye geri yüklüyoruz.

mysql -h localhost -u root -p

create database your_base;
use your_base;

mysql -uroot -p your_base < dump_file.sql

show tables;


Yedekleme dosyasının yeni makineye ve belki de yardımcı programın bulunduğu dizinde değilse tam yoluna yerleştirilmesi gerekir. (Yedeklemeyi GitHub'a yükledim ve yeni bir makineye kopyaladım). Tabloların nasıl oluşturulduğunu da eklerdim ama ekran görüntülerini kaydetmedim ve bunun 2-3 yıllık bir öğrenci için bile zor olmadığını düşünüyorum.

Tüm tablolar geri yüklendiğinde, veritabanına uzaktan erişimi kullanılabilir hale getirmenin zamanı gelmiştir. Genel olarak, bu tür komutlar başarıya yol açmadı (seçmek için yalnızca okuma izni verdi)

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

Daha doğrusu veritabanına ancak şu komutla bağlanabildim,

mysql -h localhost -u client -pclient

ama bu artık bunu yapamazdı

mysql -h 192.168.0.3 -u client -pclient

Bu benim için işe yaramadı ve bu adres üzerinden root olarak bağlanamadım.

MySQL çalışma tezgahı programı yardımcı oldu; ayarlarda localhost'u % olarak değiştirin ve istemci yardımcı olmasa da çalışır. Artık veritabanına konsoldan veya herhangi bir adresteki koddan bağlanabilirsiniz.

Veritabanını uzaktan bağlantı için kullanılabilir hale getirme

Ayrıca bir ev veya iş ağı kurmanız ve Windows güvenlik duvarını kapatmanız gerekir, aksi takdirde bu makineye ping bile atamazsınız (veritabanına bağlanmak şöyle dursun).

İşin yarısı tamamlandı, artık veritabanına evden bağlanabilmem gerekiyor.

Ağ şemasından da görebileceğiniz gibi internete ulaşmak için 192.168.0.3'ten 192.168.1.1'e (yönlendirici) gitmeniz gerekiyor, hadi ters yöne gidelim. 192.168.1.1'den 192.168.1.2'ye rotayı şu şekilde yapılandıralım:

Veritabanını uzaktan bağlantı için kullanılabilir hale getirme

Genel olarak resim görünmüyor, bu yüzden elle yazacağım:

route add 192.168.0.0 mask 255.255.255.0 gateway 192.168.1.2

Bu yalnızca bir alt ağda yapılabilir, yani 192.168.0.2 veya 192.168.0.3 adresine hemen iletemezsiniz.

Bu, yönlendiricinin 192.168.0.0/24 alt ağının nerede bulunduğunu bilmesi için gereklidir (ağların temellerini öğrenmek faydalıdır).

Şimdi 3306 adresine port yönlendirme 192.168.1.2'yı (varsayılan mysql portu (kurulum sırasında değiştirmediyseniz)) ekliyoruz.

Veritabanını uzaktan bağlantı için kullanılabilir hale getirme

Geriye kalan en zor şey, bir Linux makinesinde yönlendirme yapmaktır (iki ağ kartı vardır: 192.168.1.2 (enp3s1 arayüzü) ve 192.168.0.2 (enp3s0 arayüzü), böylece ağ kartları 192.168.1.2'den neyi aktaracaklarını bilirler. 192.168.0.2'ye ve ardından MySql ile Windows makinemize.

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

Onlar. 1. satır ilk bağlantıyı kabul ettiğimizi, 2. ve 3. satırlar her iki yöne de paket gönderebileceğimizi, 4. ve 5. satırlar ise hedef ve kaynak adreslerini değiştirdiğimiz anlamına gelir. Ve işte, evden mysql aracılığıyla bağlanabilirsiniz. Ve son olarak bunu yapan C++ kodum:

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

Artık bu programı herkese güvenle gönderebilirsiniz ve yerel olarak çalışması için yeniden yazmanıza gerek yoktur.

Kaynak: habr.com

Yorum ekle