https://downloads.mysql.com/archives/c-cpp/

windows(x86, 64-bit), ZIP Archive를 다운 받는다.
2.설치 파일 이동
-Documents->libraries 폴더 생성한다.
-libraries 폴더에 압축 해제 폴더를 복사 붙여놓기
-폴더 이름 변경 mysql8.0.32-64로 한다.
3.프로젝트 설정
구성:Release, 플랫폼x64 확인

C/C ++->일반->추가 포함 디렉터리-> 압축푼 mysql의 include까지의 주소를 입력한다.

C/C ++->전처리기->전처리기의 정의->STATIC_CONCPP;추가하기

C/C ++->코드 생성->런타임 라이브러리->다중 스레드 DLL(/MD)확인

링커->일반->추가 라이브러리 디렉터리->mysql파일의 lib64->vs14파일 경로를 붙여 넣는다

링커->입력->추가 종속성->mysqlcppconn-static.lib 넣기


파일을 프로젝트 main.cpp와 같은 디렉토링에 복사 붙여넣기를 한다.
이로써 기본 적인 준비는 끝났다.
이제 main.cpp로 가서 코드를 작성 한다.
#pragma comment(lib, "ws2_32.lib")
#include <WinSock2.h>
#include <WS2tcpip.h>
#include < string>
#include < sstream>
#include < iostream>
#include < thread>
#include < mysql/jdbc.h>
#include< istream>
using std::cout;
using std::endl;
using std::string;
//mysql 연결 하는 string문을 상수선언을 한다.
const string server = "tcp://127.0.0.1:3306";
const string username = "root";
const string password = "abc1234";
//서버측에서 보내주는 내용을 담는크기를 맥스사이즈를 정한다.
#define MAX_SIZE 1024
using std::cout;
using std::cin;
using std::endl;
using std::string;
sql::mysql::MySQL_Driver driver;
sql::Connection con;
sql::Statement stmt;
sql::PreparedStatement pstmt;
sql::ResultSet* result;
SOCKET client_sock;
string id_in;
//서버측에서 sned를 할때 받는 recv함수
int chat_recv() {
char buf [MAX_SIZE] = { };
string msg;
while (1) {
ZeroMemory(&buf, MAX_SIZE);
if (recv(client_sock, buf, MAX_SIZE, 0) > 0) {
msg = buf;
std::stringstream ss(msg);
//stringstream에서 공백과'\n'을 제외하고 문자열에서 맞는 자료형의 정보를 빼낸다
string user;
ss >> user;
if (user != id_in) cout << buf << endl;
}
else {
cout << "Server Off" << endl;
return -1;
}
}
}
//회원가입
void SignUp() {
string id, pw, name;
string check_id, check_pw;
while (1) {
cout << "사용할 아이디를 입력하세요:";
cin >> id;
pstmt = con->prepareStatement("SELECT * FROM user where id=? ;"); //유저 id의 중복 체크를 위한 select문
pstmt->setString(1, id);
pstmt->execute();
result = pstmt->executeQuery();
while (result->next()) {
check_id = result->getString(1).c_str();
}
if (check_id == id) {
cout << "이미 사용중인 아이디 입니다." << endl;
}
else if (check_id != id) {
cout << "사용할 비밀번호를 입력하세요: ";
cin >> pw;
cout << "본인의 이름을 입력하세요: ";
cin >> name;
break;
}
}
//아이디 중복 체크가 끝나면 비밀번호 이름을 user테이블에 저장한다.
pstmt = con->prepareStatement("insert into user(id, pw, user_name) values(?,?,?)");
pstmt->setString(1, id);
pstmt->setString(2, pw);
pstmt->setString(3, name);
pstmt->execute();
cout << "회원가입 성공" << endl;
}

//저장된 채팅내용 가져오기
void Store(string check_id) {
string StoreUser, StoreMsg; //user테이블에서 id랑,chatting내용을 담을 변수
bool id = true;
cout << "저장된 내용" << endl;
con->setSchema("project");
pstmt = con->prepareStatement("SELECT * FROM chatting ;");
result = pstmt->executeQuery();
while (result->next()) {
StoreUser = result->getString("id").c_str();
StoreMsg = result->getString("chat").c_str();
//처음 입장해서 채팅내용이 없으면 전 내용을 못보게 설정
if (StoreUser == check_id)
{
id = false;
}
if (id == false)
{
cout << StoreUser << " : " << StoreMsg << endl;
}
}
}

//비밀번호 변경하는 함수
void Revise() {
string id, pw;
string check_id, check_pw;
cout << "아이디를 입력하세요. : ";
cin >> id;
cout << "비밀번호를 입력하세요";
cin >> pw;
pstmt = con->prepareStatement("SELECT * FROM user where id = ? and pw =?;");
pstmt->setString(1, id);
pstmt->setString(2, pw);
pstmt->execute();
result = pstmt->executeQuery();
//user의 id,pw를 while문을 이용해 check_id,check_pw에 담아서
입력한 아이디와 비밀번호와 비교한다.
while (result->next()) {
check_id = result->getString(1).c_str();
check_pw = result->getString(2).c_str();
}
if (check_id != id || check_pw != pw) {
cout << "아이디,비밀번호가 맞지 않습니다.\n";
}
else {
cout << "변경할 비밀번호를 입력해 주세요. : ";
cin >> pw;
pstmt = con->prepareStatement("select id from user");
result = pstmt->executeQuery();
while (result->next()) {
pstmt = con->prepareStatement("UPDATE user SET pw = ? WHERE id = ?");
pstmt->setString(1, pw);
pstmt->setString(2, id);
pstmt->executeQuery();
}
cout << "변경 되었습니다\n";
}
}

//회원탈퇴
void Leave() {
string id, pw, name;
string check_id, check_pw, check_name;
cout << "아이디를 입력해주세요: ";
cin >> id;
cout << "비밀번호를 입력해주세요: ";
cin >> pw;
cout << "이름을 입력해주세요: ";
cin >> name;
pstmt = con->prepareStatement("SELECT * FROM user where id = ? and pw = ? and user_name = ?");
pstmt->setString(1, id);
pstmt->setString(2, pw);
pstmt->setString(3, name);
pstmt->execute();
result = pstmt->executeQuery();
while (result->next()) {
check_id = result->getString(1).c_str();
check_pw = result->getString(2).c_str();
check_name = result->getString(3).c_str();
}
if (check_id != id || check_pw != pw || check_name != name) {
cout << "회원 정보가 일치하지 않습니다.\n";
}
else {
pstmt = con->prepareStatement("DELETE FROM user WHERE id = ?");
pstmt->setString(1, id);
result = pstmt->executeQuery();
pstmt = con->prepareStatement("DELETE FROM chatting WHERE id = ?");
pstmt->setString(1, id);
result = pstmt->executeQuery();
cout << "탈퇴되었습니다.\n";
}
//회원 탈퇴시 저장된 대화 내용도 삭제된다.
}

//테이블을 생성 하는 함수
void Createtable() {
stmt->execute("CREATE TABLE user (id varchar(50) PRIMARY KEY not null, pw VARCHAR(50), user_name VARCHAR(50));");
stmt->execute("create table chatting(id varchar(50), chat varchar(250) not null, foreign key(id) references user(id) on update cascade on delete cascade);");
stmt->execute("create table direct_msg(send_id varchar(50), recv_id varchar(50), msg varchar(250), foreign key(send_id) references user(id) on update cascade on delete cascade);");
delete stmt;
}
//메인문
int main()
{
WSADATA wsa;
int choice = 0;
bool log = true;
int code = WSAStartup(MAKEWORD(2, 2), &wsa);
// sql 연결
try {
driver = sql::mysql::get_mysql_driver_instance();
con = driver->connect(server, username, password);
}
catch (sql::SQLException& e) {
cout << "Could not connect to server. Error message: " << e.what() << endl;
exit(1);
}
con->setSchema("project");
//한국어를 받기위한 설정문
stmt = con->createStatement();
stmt->execute("set names euckr");
if (stmt) { delete stmt; stmt = nullptr; }
stmt = con->createStatement();
delete stmt;
// show tables을 해서 테이블이 없으면 Createtable()문을 실행한다.
string check_usertable;
stmt = con->createStatement();
pstmt = con->prepareStatement("show tables");
result = pstmt->executeQuery();
while (result->next()) {
check_usertable = result->getString(1).c_str();
}
if (check_usertable == "") {
Createtable();
}
if (!code) {
//client측 소켓을 만드는 문
client_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN client_addr = {};
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(8080);
InetPton(AF_INET, TEXT("127.0.0.1"), &client_addr.sin_addr);
while (true) {
cout << "1: 로그인하기 2: 회원가입하기 3: 비밀번호 수정 4:회원탈퇴" << endl;
cin >> choice;
// 로그인
if (choice == 1) {
string pw;
string check_id, check_pw;
cout << "ID:";
cin >> id_in;
cout << "PW:";
cin >> pw;
pstmt = con->prepareStatement("SELECT * FROM user where id=? and pw=?;");
pstmt->setString(1, id_in);
pstmt->setString(2, pw);
pstmt->execute();
result = pstmt->executeQuery();
while (result->next()) {
check_id = result->getString(1).c_str();
check_pw = result->getString(2).c_str();
}
if (check_id == id_in && check_pw == pw) {
cout << "로그인 되었습니다." << endl;
//로그인후 서버와 커넥트 한다.
while (1) {
if (!connect(client_sock, (SOCKADDR*)&client_addr, sizeof(client_addr))) {
cout << "Server Connect" << endl;
send(client_sock, id_in.c_str(), id_in.length(), 0);
break;
}
cout << "Connecting..." << endl;
}
std::thread th2(chat_recv);
Store(check_id);
while (1) {
string text;
std::getline(cin, text);
//대화 내용을 getline을 이용해 띄어쓰기가 있어도 buffer에 담아 서버로 보내준다.
const char* buffer = text.c_str(); // string형을 char* 타입으로 변환
send(client_sock, buffer, strlen(buffer), 0);
}
th2.join();
closesocket(client_sock);
}
else {
cout << "로그인에 실패했습니다." << endl;
continue;
}
}
if (choice == 2)
{
SignUp();
continue;
}
if (choice == 3)
{
Revise();
continue;
}
if (choice == 4) {
int num;
cout << "정말 탈퇴하시겠습니까? (예: 1 아니오: 2)\n";
cin >> num;
if (num == 1) {
Leave();
}
else {
choice = 0;
}
continue;
}
}
WSACleanup();
}
}
