1.mysql 数据库的建立
首先在虚拟机终端上利用 ifconfig 获取虚拟机IP。
然后在本地计算机浏览器地址栏输入 http://192.168.200.128/phpmyadmin 如果载入不成功检查Ubuntu是否安装phpmyadmin。
输入mysql的账号和密码进入。并且新建一个名为 sdb 的数据库
及其对应的表:
privilege
users
2.后端PHP代码
db_info.php
/**
* Created by PhpStorm.
* User: pldq
* Date: 16-12-13
* Time: 下午8:31
*/
#echo "From db_info.php";
# databases infomation
static $DB_HOST="localhost";
static $DB_NAME="sdb";
static $DB_USER="root";
static $DB_PASS="******";
global $con;
$con = mysqli_connect($DB_HOST, $DB_USER, $DB_PASS);
if ($con == null) {
die("FAILED|Could not connect:" . mysqli_error() . "
");
}
if (!mysqli_select_db($con, "sdb")) {
die("FAILED|Could't use foo: " . mysqli_error());
}
?>
login.php
'db_info.php');
// echo "Hello World!";
// echo $_REQUEST["username"];
// echo $_REQUEST["psd"];
$username = $_POST["username"];
$psd = $_POST["psd"];
// $phone = $_POST["phone"];
// $email = $_POST["email"];
$sql_username = "Select * from users WHERE username = '" . $username . "'";
$mysqli_result = mysqli_query($con, $sql_username);
$row = mysqli_fetch_array($mysqli_result);
if (mysqli_num_rows($mysqli_result) == 0) {
die("FAILED|The username is not existed!");
}
if ($row['password'] === $psd and strlen($psd) > 6)
{
$str_ret = "SUCCEED|SUCCEED LOGIN IN THE SYSTEM!|";
$sql_get_privilege = "Select * from privilege WHERE username = '" . $username . "'";
$mysqli_privilege_result = mysqli_query($con, $sql_get_privilege);
if (mysqli_num_rows($mysqli_result) == 0) {
$_SESSION['user'] = $username;
die($str_ret);
} else {
$row = mysqli_fetch_array($mysqli_privilege_result);
$_SESSION['user'] = $username;
$_SESSION['rightstr'] = $row['rightstr'];
die($str_ret . $row['rightstr']);
}
} else {
die("FAILED|The password is incorrect!");
}
mysqli_close($con); // close db connect
?>
然后将代码上传到Ubuntu 站点目录下
这样网页后端就编写成功了!
3.MFC 端
1、利用 MFC 生成向导生成一个基于对话框的程序。
使用GDI绘图:
#include
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
// Bitmap* m_mainImage; // 声明为类成员
BOOL CManagementSystemDlg::OnInitDialog()
{
// 初始化 GDI+
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
// !其余代码没有进行修改、删除
}
void CManagementSystemDlg::OnClose()
{
// 释放GDI+
GdiplusShutdown(m_gdiplusToken);
}
绘制图片:
#define IMAGE_MAIN_FILENAME L"Important\\res_login\\main.jpg"
BOOL CManagementSystemDlg::OnInitDialog()
{
// 加载图片到内存
m_mainImage = Bitmap::FromFile(IMAGE_MAIN_FILENAME);
}
void CManagementSystemDlg::OnPaint()
{
CClientDC Clientdc(this);
Graphics graphics(Clientdc.GetSafeHdc());
// 绘制图片
graphics.DrawImage(m_mainImage, 0, 0, m_mainImage->GetWidth(), m_mainImage->GetHeight());
}
然后编译运行、、、
但是运行后发现窗口并不能实现拖动。为了实现窗口拖动我们还需要让对话框响应 WM_NCHITTEST 消息。让它把点击再窗口客户区的消息响应为在标题栏点击的消息。
LRESULT CManagementSystemDlg::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rc;
GetClientRect(&rc);
ClientToScreen(&rc);
int x = point.x;
int y = point.y;
if (x >= rc.left && x <= rc.right && y >= rc.top && y <= rc.bottom)
{
return HTCAPTION;
}
else {
return CDialogEx::OnNcHitTest(point);
}
}
退出按钮的事件代码:
void CManagementSystemDlg::OnBnClickedButtonExit()
{
// TODO:在此添加控件通知处理程序代码
this->SendMessage(WM_CLOSE, 0, 0);
}
登陆按钮的事件代码:
HTTP访问:
1. 利用MFC 里面的CSession、CHttpConnection等函数:(实现失败!)
#include
void Ansi2Wchar(std::string strSource, CString& strDest)
{
int length = 0;
length = ::MultiByteToWideChar(CP_ACP, 0, strSource.c_str(), strSource.length(), 0, 0);
WCHAR* Buffer = new WCHAR[length + 1];
memset(Buffer, 0, (length + 1) * sizeof(WCHAR));
::MultiByteToWideChar(CP_ACP, 0, strSource.c_str(), strSource.length(), Buffer, length);
strDest = Buffer;
delete[] Buffer;
}
void Wchar2Ansi(CString strSource, std::string& strDest)
{
int length = 0;
length = ::WideCharToMultiByte(CP_ACP, 0, strSource.GetBuffer(), strSource.GetLength(), 0, 0, 0, 0);
strSource.ReleaseBuffer();
CHAR* Buffer = new CHAR[length + 1];
memset(Buffer, 0, sizeof(CHAR)* (length + 1));
::WideCharToMultiByte(CP_ACP, 0, strSource.GetBuffer(), strSource.GetLength(), Buffer, length, 0, 0);
strSource.ReleaseBuffer();
strDest = Buffer;
delete[] Buffer;
}
void CManagementSystemDlg::OnBnClickedButtonLogin()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString strUrl = L"http://192.168.200.128/myAdminSystem/login.php";
DWORD dwServiceType = AFX_INET_SERVICE_HTTP;
CString strServer = L"";
CString strObject = L"";
INTERNET_PORT nPort = 80;
if (!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort))
{
return;
}
CInternetSession mysession(L"session", 0);
mysession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 1000 * 20);
mysession.SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000);
mysession.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);
CHttpConnection* mycon = mysession.GetHttpConnection(strServer, INTERNET_FLAG_KEEP_CONNECTION, nPort);
CHttpFile* myfile = mycon->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, 0, 1, 0, L"HTTP/1.1", INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE);
CString strPostData = L"username=" + strUSER + L"&psd=" + strPsd;
std::string strPost = "";
Wchar2Ansi(strPostData, strPost);
CString strHeaders = L"Content-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n";
BOOL result = myfile->SendRequest(strHeaders, (LPVOID)strPost.c_str(), strPost.size());
strHeaders.ReleaseBuffer();
strPostData.ReleaseBuffer();
CHAR Buffer[1024 + 1] = { 0 };
memset(Buffer, 0, (1024 + 1) * sizeof(CHAR));
std::string strRawResponse = "";
UINT nReaded = 0;
while ((nReaded = myfile->Read((void*)Buffer, 1024)) > 0)
{
Buffer[nReaded] = '\0';
strRawResponse += Buffer;
memset(Buffer, 0, (1024 + 1) * sizeof(CHAR));
}
CString strResponse = L"";
Ansi2Wchar(strRawResponse, strResponse);
if (strResponse.GetLength() <= 0)
{
MessageBox(L"获取数据失败!", L"Info", MB_OK | MB_ICONWARNING);
return;
}
}
这个 Bug 很奇怪,当我打开 Fiddler 进行抓包时 SendRequest 可以成功使用,当我关闭 Fiddler 的抓包功能时它会弹出 “无法与服务器建立连接的信息框”
2. 利用WinHttp 的 com 组件智能指针编程(实现简单、现使用)
#import "C:\\windows\\system32\\winhttp.dll"
#define STRING_LOGIN_HOST_ADDRESS L"http://192.168.200.128/myAdminSystem/login.php"
void CManagementSystemDlg::OnBnClickedButtonLogin()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CString strPostData = L"username=" + strUSER + L"&psd=" + strPsd;
// using com programming winhttp
WinHttp::IWinHttpRequestPtr ptrHttp = nullptr;
ptrHttp.CreateInstance(__uuidof(WinHttp::WinHttpRequest));
if (0 != ptrHttp->Open(L"POST", STRING_LOGIN_HOST_ADDRESS))
{
MessageBox(L"服务器连接失败!", L"Info", MB_OK | MB_ICONSTOP);
return;
}
ptrHttp->SetRequestHeader(L"User-Agent", L" Mozilla / 5.0 (Windows NT 6.1; WOW64) AppleWebKit / 537.36 (KHTML, like Gecko) Chrome / 50.0.2661.102 Safari / 537.36");
ptrHttp->SetRequestHeader(L"Content-Type", L"application/x-www-form-urlencoded");
ptrHttp->Send(strPostData.GetBuffer());
strPostData.ReleaseBuffer();
CString strResult = ptrHttp->GetResponseText();
CString strCookie = ptrHttp->GetResponseHeader(L"Set-Cookie"); // get http post cookie
strCookie.Replace(L"; path=/", L"");
}
对HTTP返回消息的处理:
if (strResult.GetLength() <= 0)
{
MessageBox(L"获取数据失败!", L"Info", MB_OK | MB_ICONWARNING);
return;
}
if (-1 == strResult.Find(L"FAILED"))
{
int index = 0;
CString strCaption = strResult.Mid(index, strResult.Find(L"|", index) - index);
index = strResult.Find(L"|", index) + 1;
CString strInformation = strResult.Mid(index, strResult.Find(L"|", index) - index);
index = strResult.Find(L"|", index) + 1;
CString session = strResult.Mid(index, strResult.GetLength() - index);
MessageBox(strInformation, strCaption, MB_OK | MB_ICONINFORMATION);
// TODO
} else {
int index = 0;
CString strCaption = strResult.Mid(index, strResult.Find(L"|", index) - index);
index = strResult.Find(L"|", index) + 1;
CString strInformation = strResult.Mid(index, strResult.GetLength() - index);
MessageBox(strInformation, strCaption, MB_OK | MB_ICONSTOP);
return;
}
这样一个登陆功能就成功实现了!