Commit 918e3391 by 刘帅

1. 实现支付过程中弹出、隐藏界面功能

parents
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
*.manifest
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
#-------------------------------------------------
#
# Project created by QtCreator 2017-12-12T18:08:21
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FmclientUi
TEMPLATE = app
LIBS += -L$$PWD/lib/
DESTDIR = $$PWD/bin
win32 {
LIBS += -lfmcrypt
}
SOURCES += main.cpp\
widget.cpp \
qfmclient.cpp
HEADERS += widget.h \
fmcrypt.h \
qfmclient.h
FORMS += widget.ui
File added
#ifndef __ZHCRYPT_H__
#define __ZHCRYPT_H__
extern "C" {
int ZH_getKey(char * keyBuf, char * ctrlBuf, void * pvInfo);
char * ZH_encodeSendData(char * codeBuf, char * buf, int length, int * eLength, char * keyBuf, int keyLengh);
char * ZH_decodeRecvData(char * codeBuf, char * buf, int length, int * dLength, char * keyBuf, int keyLength, int * pcurKeyPos);
int ZH_encodeBkData(char * pOrgData, int dataLen, char * keyBuf, int keyLen, char * pCodeBuf);
void ZH_decodeBkData(char * pCodeBuf, char * pOrgBuf,int totalLen);
int ZH_checkChkValue(char * pJsonData, int dLength, int tbckValue);
}
#endif
File added
#include "widget.h"
#include <QApplication>
#include "qfmclient.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
QFmClient client;
QObject::connect(&client,&QFmClient::HideUi, &w, &Widget::hide,Qt::QueuedConnection);
QObject::connect(&client,&QFmClient::ShowUi, &w, &Widget::show,Qt::QueuedConnection);
client.start();
return a.exec();
}
#include "qfmclient.h"
#include "fmcrypt.h"
#include <windows.h>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QFile>
#include <Qdebug>
#include <QApplication>
#include <QWidget>
#ifdef WIN32
#include <direct.h>
#include <windows.h>
#include <winsock.h>
#include <DbgHelp.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "fmcrypt.lib")
//#pragma comment(lib, "DbgHelp.lib")
#else
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <unistd.h>
#endif
unsigned int QFmClient::s_reqCount = 0;
QFmClient::QFmClient(QObject *parent) : QThread(parent)
{
_endflag = false;
_fmMSS = 1024;
}
bool QFmClient::Init(QString proxy_IP, unsigned short proxy_port, unsigned short listen_prot, unsigned short long_timeout, unsigned short short_timeout)
{
if(proxy_IP.size() == 0 ||
proxy_port <= 0 ||
listen_prot <= 0 ||
short_timeout <= 0 ||
long_timeout <= 0
)
return false;
if(proxy_IP.toStdString().size() > 30)
return false;
strcpy(_proxyIP, proxy_IP.toStdString().c_str());
_proxyIP[proxy_IP.toStdString().size()] = 0;
this->_proxyPort = proxy_port;
this->_clientPort = listen_prot;
this->_shortTimeOut = short_timeout;
this->_longTimeOut = long_timeout;
#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2,2);
err = WSAStartup(wVersionRequested, &wsaData);
#endif
memset(_codeKey, 0, MAX_CODE_KEY);
memset(_codeBuf, 0, MAX_BUF_LEN);
memset(_recvbuf, 0, MAX_BUF_LEN);
memset(_tempbuf, 0, MAX_BUF_LEN);
memset(_sendbuf, 0, MAX_BUF_LEN);
_codeFlag = 1;
return true;
}
int QFmClient::RecvSockData(int sock, char *buffer, int length)
{
#ifdef WIN32
return ::recv(sock, buffer, length, 0);
#else
return ::read(sock, buffer, length);
#endif
}
void QFmClient::WaitAndSleep(int elapse)
{
#ifdef WIN32
Sleep(elapse);
#else
sleep(elapse/1000);
#endif
}
bool QFmClient::WaitForConnectReqFromPos()
{
int sin_size = sizeof(struct sockaddr_in);
struct sockaddr_in c_add;
if(0 < _acceptedSock)
{
RecvSockData(_acceptedSock, _recvbuf, (MAX_BUF_LEN - 1));
CloseSocket(&_acceptedSock);
}
_acceptedSock = accept(_listenSock, (struct sockaddr *)(&c_add), &sin_size);
if(-1 == _acceptedSock)
{
qDebug() << "accept socket fail!\r\n";
return false;
}
qDebug() << "accept ok, ZF Client get connection from POS!\r\n";
return true;
}
int QFmClient::CheckIsCompleteJsonData(int * count, char * data)
{
int loop = 0;
while(data[loop])
{
if ('{' == data[loop])
{
(*count) ++;
}
if ('}' == data[loop])
{
(*count) --;
}
loop++;
if (0 == (*count))
{
break;
}
}
return loop;
}
#ifdef WIN32
int QFmClient::GBKToUTF8(unsigned char * lpGBKStr,int gbkLen, unsigned char * lpUTF8Str,int nUTF8StrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0;
if(!lpGBKStr) //如果GBK字符串为NULL则出错退出
return 0;
nRetLen = MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,gbkLen,NULL,NULL); //获取转换到Unicode编码后所需要的字符空间长度
//lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间
lpUnicodeStr = (WCHAR*)malloc( sizeof(WCHAR)*(nRetLen + 1));
nRetLen = MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,gbkLen,lpUnicodeStr,nRetLen); //转换到Unicode编码
if(!nRetLen) //转换失败则出错退出
return 0;
nRetLen = WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,nRetLen,NULL,0,NULL,NULL); //获取转换到UTF8编码后所需要的字符空间长度
if(!lpUTF8Str) //输出缓冲区为空则返回转换后需要的空间大小
{
if(lpUnicodeStr)
free(lpUnicodeStr);
return nRetLen;
}
if(nUTF8StrLen < nRetLen) //如果输出缓冲区长度不够则退出
{
if(lpUnicodeStr)
free(lpUnicodeStr);
return 0;
}
nRetLen = WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,nRetLen,(char *)lpUTF8Str,nUTF8StrLen,NULL,NULL); //转换到UTF8编码
if(lpUnicodeStr)
free(lpUnicodeStr);
return nRetLen;
}
int QFmClient::UTF8ToGBK(unsigned char * lpUTF8Str,unsigned char * lpGBKStr,int nGBKStrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0;
if(!lpUTF8Str) //如果UTF8字符串为NULL则出错退出
return 0;
nRetLen = MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,NULL,NULL); //获取转换到Unicode编码后所需要的字符空间长度
//lpUnicodeStr = new WCHAR[nRetLen + 1]; //为Unicode字符串空间
lpUnicodeStr = (WCHAR*)malloc( sizeof(WCHAR)*(nRetLen + 1));
nRetLen = MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,lpUnicodeStr,nRetLen); //转换到Unicode编码
if(!nRetLen) //转换失败则出错退出
return 0;
nRetLen = WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,NULL,NULL,NULL,NULL); //获取转换到GBK编码后所需要的字符空间长度
if(!lpGBKStr) //输出缓冲区为空则返回转换后需要的空间大小
{
if(lpUnicodeStr)
free(lpUnicodeStr);
return nRetLen;
}
if(nGBKStrLen < nRetLen) //如果输出缓冲区长度不够则退出
{
if(lpUnicodeStr)
free(lpUnicodeStr);
return 0;
}
nRetLen = WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,(char *)lpGBKStr,nRetLen,NULL,NULL); //转换到GBK编码
if(lpUnicodeStr)
free(lpUnicodeStr);
return nRetLen;
}
#endif
char * QFmClient::DecodeRecvData(char * buf, int length, int * dLength)
{
int curKeyPos = _curKeyPos;
char * rltPtr = ZH_decodeRecvData(_codeBuf, buf, length, dLength, (char *)_codeKey, _keyLength, &curKeyPos);
_curKeyPos = (char)curKeyPos;
return rltPtr;
}
int QFmClient::WaitAndReadDataFromPos(int type, int flag)
{
qDebug() << "wait and receive data from POS...\r\n";
_rcvLength = 0;
int recbytes, finLen, curPos = 0, prosLen = 0, checkCount = 0;
//int i = 0;
do
{
char * precvBuf;
if (0 >= (recbytes = RecvSockData(_acceptedSock, _tempbuf, (MAX_BUF_LEN - 1))))
{
#ifdef WIN32
qDebug() << "recv() return : " << recbytes << ";error : " << WSAGetLastError() << ";\r\n";
#endif
qDebug() << "read data from socket " << _acceptedSock << " fail!\r\n";
return -1;
}
#ifdef WIN32
if(type)
{
memcpy( _sendbuf, _tempbuf, recbytes );
//recbytes = GBKToUTF8( (unsigned char *)_sendbuf, recbytes, (unsigned char *)_tempbuf, MAX_BUF_LEN - 100);
}
#endif
precvBuf = _tempbuf;
_tempbuf[recbytes] = '\0';
if(1 == flag)
precvBuf = DecodeRecvData(_tempbuf, recbytes, &recbytes);
qDebug() << "received data from socket " << _acceptedSock << " : " << precvBuf;
while(0 < recbytes)
{
finLen = CheckIsCompleteJsonData(&checkCount, precvBuf + prosLen);
if (((0 == checkCount) && ( '}' != precvBuf[ prosLen + finLen - 1])) || ((MAX_BUF_LEN - 1) < curPos + finLen))
{
qDebug() << "checkCount out!\r\n";
return -1;
}
memcpy(_recvbuf + curPos, precvBuf + prosLen, finLen);
curPos += finLen;
prosLen += finLen;
if (0 == checkCount)
{
_recvbuf[curPos] = '\0';
_rcvLength = curPos;
curPos = 0;
checkCount = 0;
qDebug() << "checkCount = 0";
goto finishRecv;
}
recbytes -= finLen;
}
prosLen = 0;
}while(1);
finishRecv:
return 0;
}
void QFmClient::AddReqCount(QJsonObject& object)
{
s_reqCount %= MAX_REQ_COUNT;
s_reqCount ++;
object["clientReqCount"] = (int)s_reqCount;
}
int QFmClient::CheckReqFromPos(char * pJsonData, int dLength, int chkValue)
{
return ZH_checkChkValue(pJsonData, dLength, chkValue);
}
int QFmClient::ProcessPosReqData(QJsonObject& object)
{
int flag = 0;
QByteArray recvdata(_recvbuf);
QJsonParseError json_error;
QJsonDocument doc = QJsonDocument::fromJson(recvdata, &json_error);
if(json_error.error != QJsonParseError::NoError || !doc.isObject())
{
qDebug() << "error request json data!\r\n";
return -1;
}
object = doc.object();
do
{
_sockTimeOut = _longTimeOut;
if(object.contains("reqtype"))
{
if(object["reqtype"] != 72)
{
_sockTimeOut = _shortTimeOut;
}
if(object["reqtype"] == 72 || object["reqtype"] == 71)
{
flag = 1;
}
}else
{
qDebug() << "not found reqtype";
flag = -1;
break;
}
if(!object.contains("checkValue") || !object["checkValue"].isDouble())
{
qDebug() << "checkValue failed!\r\n";
flag = -1;
break;
}
AddReqCount(object);
}while(0);
return flag;
}
int QFmClient::Try2ConnectZhProxy()
{
struct sockaddr_in proxyAddr;
int rlt = 0;
unsigned long ul = 1;
//unsigned long sendsize = 32;
BOOL bNoDelay = TRUE;
fd_set fs;
struct timeval cntTO = {_shortTimeOut,0};
#ifdef WIN32
int sockTimeOut = _sockTimeOut * 1000;
#else
struct timeval sockTimeOut={_sockTimeOut,0};
#endif
_zhProxySock = socket(AF_INET, SOCK_STREAM, 0);
memset(&proxyAddr, 0, sizeof(struct sockaddr_in));
proxyAddr.sin_addr.s_addr =inet_addr(_proxyIP);
proxyAddr.sin_family = AF_INET;
proxyAddr.sin_port = htons(_proxyPort);
#ifdef WIN32
ioctlsocket(_zhProxySock, FIONBIO, &ul);
#else
ioctl(_zhProxySock, FIONBIO, &ul);
#endif
::connect(_zhProxySock, (struct sockaddr *)&proxyAddr, sizeof(struct sockaddr));
FD_ZERO(&fs);
FD_SET(_zhProxySock, &fs);
rlt = select(_zhProxySock + 1, 0, &fs, 0, &cntTO);
if (0 >= rlt)
{
#ifdef WIN32
closesocket(_zhProxySock);
#else
closesocket(_zhProxySock);
#endif
return -1;
}
ul = 0;
#ifdef WIN32
ioctlsocket(_zhProxySock, FIONBIO, &ul);
#else
ioctl(_zhProxySock, FIONBIO, &ul);
#endif
#ifdef WIN32
//setsockopt(g_clientInfo.zhProxySock, SOL_SOCKET, SO_SNDBUF, (char*)&sendsize,sizeof(int));
setsockopt(_zhProxySock, IPPROTO_TCP, TCP_NODELAY, (char FAR *)&bNoDelay, sizeof(BOOL));
setsockopt(_zhProxySock, SOL_SOCKET, SO_SNDTIMEO, (char *)&sockTimeOut, sizeof(int));
setsockopt(_zhProxySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&sockTimeOut, sizeof(int));
#else
setsockopt(_zhProxySock, SOL_SOCKET, SO_RCVTIMEO, (char *)&sockTimeOut, sizeof(struct timeval));
setsockopt(_zhProxySock, SOL_SOCKET, SO_SNDTIMEO, (char *)&sockTimeOut, sizeof(struct timeval));
#endif
return 0;
}
void QFmClient::GetKey()
{
_curKeyPos = 0;
_keyLength = ZH_getKey((char *)_codeKey, _tempbuf, 0);
}
char * QFmClient::EncodeSendData(char * buf, int length, int * eLength)
{
return ZH_encodeSendData(_codeBuf, buf, length, eLength, (char *)_codeKey, _keyLength);
}
int QFmClient::SendSocketData(int sock, char * buf, int length, int flag)
{
char * psendBuf = buf;
int tmplen = 0, tmp = _fmMSS, tmpsize = _fmMSS, len = 0;
if (1 == flag)
{
psendBuf = EncodeSendData(buf, length, &length);
}
#ifdef WIN32
if(length <= tmp)
{
return send(sock, psendBuf, length, 0);
}else
{
while(tmplen < length)
{
if(tmplen + tmp > length)
{
tmpsize = length - tmplen;
tmplen = length;
}else
{
tmpsize = tmp;
tmplen += tmp;
}
send(sock, psendBuf + len, tmpsize, 0);
len = tmplen;
}
}
return tmplen;
#else
return write(sock, psendBuf, length);
#endif
}
int QFmClient::SendCtrlInfo2Proxy()
{
int sendRlt, offset = 1;
_tempbuf[0] = _codeFlag;
if (_codeFlag)
{
GetKey();
offset += (1 + _tempbuf[1]);
}
_tempbuf[offset] = _sockTimeOut;
sendRlt = SendSocketData(_zhProxySock, _tempbuf, MAX_CTRL_INFO_LEN, 0);
if (sendRlt != MAX_CTRL_INFO_LEN)
{
#ifdef WIN32
qDebug() << "recv() return : " << sendRlt << ";error : " << WSAGetLastError() << ";\r\n";
#endif
return -1;
}
return 0;
}
int QFmClient::RecvAndCheckDataFromSock(int sock, int flag, int type) //type = 0 proxy re, = 1 pos re
{
int recbytes, finLen, curPos = 0, prosLen = 0, checkCount = 0;
//int i = 0;
do
{
char * precvBuf;
if (0 >= (recbytes = RecvSockData(sock, _tempbuf, (MAX_BUF_LEN - 1))))
{
#ifdef WIN32
qDebug() << "recv() return : " << recbytes << ";error : " << WSAGetLastError() << ";\r\n";
#endif
qDebug() << "read data from socket "<< sock <<" fail!\r\n";
return -1;
}
#ifdef WIN32
if(type)
{
memcpy( _sendbuf, _tempbuf, recbytes );
recbytes = GBKToUTF8( (unsigned char *)_sendbuf, recbytes, (unsigned char *)_tempbuf, MAX_BUF_LEN - 100);
}
#endif
precvBuf = _tempbuf;
_tempbuf[recbytes] = '\0';
if (1 == flag)
{
precvBuf = DecodeRecvData(_tempbuf, recbytes, &recbytes);
}
qDebug() << "received data from socket " << sock << " : " << precvBuf;
while(0 < recbytes)
{
finLen = CheckIsCompleteJsonData(&checkCount, precvBuf + prosLen);
if (((0 == checkCount) && ( '}' != precvBuf[ prosLen + finLen - 1])) || ((MAX_BUF_LEN - 1) < curPos + finLen))
{
qDebug() << "checkCount out!\r\n";
return -1;
}
memcpy(_recvbuf + curPos, precvBuf + prosLen, finLen);
curPos += finLen;
prosLen += finLen;
if (0 == checkCount)
{//a complete json data received
_recvbuf[curPos] = '\0';
_rcvLength = curPos;
curPos = 0;
checkCount = 0;
qDebug() << "checkCount = 0";
goto finishRecv;
}
recbytes -= finLen;
}
prosLen = 0;
}while(1);
finishRecv:
return 0;
}
int QFmClient::SendData2ZhProxyAndWaitRspData()
{
int rlt, length;
length = strlen(_sendbuf);
rlt = SendSocketData(_zhProxySock, _sendbuf, length, _codeFlag);
if (rlt != length)
{
#ifdef WIN32
qDebug() << "recv() return : " << rlt << ";error : " << WSAGetLastError() << ";\r\n";
#endif
qDebug() << "send data to socket failed!\r\n";
return -1;
}
qDebug() << "wait and receive data from ZH Proxy...\r\n";
if (0 != RecvAndCheckDataFromSock(_zhProxySock, _codeFlag,0))
{
qDebug() << "receive data or check data failed\r\n";
return -1;
}
return 0;
}
int QFmClient::CheckRecvedData()
{
QByteArray recvdata(_recvbuf);
QJsonParseError json_error;
QJsonDocument doc = QJsonDocument::fromJson(recvdata, &json_error);
if(json_error.error != QJsonParseError::NoError || !doc.isObject())
{
qDebug() << "error request json data!\r\n";
return -1;
}
return 0;
}
int QFmClient::ProcessZhProxyRspDataAndSend2Pos()
{
int rlt, length;
if (0 != CheckRecvedData())
{
return -1;
}
memcpy( _tempbuf, _recvbuf, strlen(_recvbuf) );
//UTF8ToGBK(g_clientInfo.tmpBuf, g_clientInfo.rcvBuf,MAX_SEND_RCV_BUF_LEN -100);
length = strlen(_recvbuf);
rlt = SendSocketData(_acceptedSock, _recvbuf, length, 0);
if (rlt != length)
{
#ifdef WIN32
qDebug() << "recv() return : " << rlt << ";error : " << WSAGetLastError() << ";\r\n";
#endif
return -1;
}
return 0;
}
void QFmClient::BackupPosReq(char * req)
{
QFile file(qApp->applicationDirPath()+ "/" + ROLL_BACK_FILE_NAME);
int wl = strlen(req);
if(file.open(QFile::ReadWrite))
{
wl = ZH_encodeBkData(req, wl, (char *)_codeKey, _keyLength, _codeBuf);
file.write(_codeBuf, wl);
file.close();
}
}
void QFmClient::run()
{
if(!Init("115.159.63.201", 29534, 34952, 30, 5))
{
qDebug() << "Init QFmClient failed";
emit Error("Init QFmClient failed");
}
else
qDebug() << "Init QFmClient success.";
do
{
CloseSocket(&_acceptedSock);
CloseSocket(&_listenSock);
CheckRollBackData();
if(!StartListenport())
{
qDebug() << "Start Listen port : " << _clientPort <<" failed";
WaitAndSleep(3000);
continue ;
}
do
{
int rlt, needBackup;
if (!WaitForConnectReqFromPos())
{
break;
}
if (0 != WaitAndReadDataFromPos(1, 0))
{
CloseSocket(&_acceptedSock);
continue;
}
emit ShowUi();
QJsonObject object;
char temp_recv[MAX_BUF_LEN] = {0};
strcpy(temp_recv, _recvbuf);
needBackup = ProcessPosReqData(object);
if (0 > needBackup)
{
CloseSocket(&_acceptedSock);
emit HideUi();
continue;
}
if (0 != Try2ConnectZhProxy())
{
qDebug() << "connect to proxy failed";
CloseSocket(&_acceptedSock);
emit HideUi();
continue;
}
if (0 != SendCtrlInfo2Proxy())
{
CloseSocket(&_acceptedSock);
emit HideUi();
continue;
}
memset(_sendbuf, 0, MAX_BUF_LEN);
QString temp = QString(QJsonDocument(object).toJson());
strcpy(_sendbuf, temp.toStdString().c_str());
rlt = SendData2ZhProxyAndWaitRspData();
emit HideUi();
OutputDebugString(L"hide Ui");
if (0 == rlt)
{
rlt = ProcessZhProxyRspDataAndSend2Pos();
}
CloseSocket(&_zhProxySock);
if (0 != rlt)
{
if (1 == needBackup)
{//is write off data, need to check roll back
BackupPosReq(temp_recv);
break;
}
}
CloseSocket(&_acceptedSock);
}while(1);
if(!_endflag)
WaitAndSleep(3000);
}while(!isInterruptionRequested());
qDebug() << "Exit ZH Client!\r\n";
OutputDebugString(L"Exit ZH Client!\r\n");
#ifdef WIN32
WSACleanup();
#endif
}
void QFmClient::quit()
{
_endflag = true;
closesocket(_listenSock);
requestInterruption();
OutputDebugString(L"close listen socket");
}
void QFmClient::CloseSocket(int *sock)
{
if(0 < *sock)
{
#ifdef WIN32
closesocket(*sock);
#else
close(*sock);
#endif
*sock = 0;
}
}
bool QFmClient::StartListenport()
{
struct sockaddr_in s_add;
int reuse = 1;
#ifdef WIN32
_listenSock = socket(AF_INET, SOCK_STREAM, 0);
#else
_listenSock = socket(AF_INET, SOCK_STREAM, 0);
#endif
if(-1 == _listenSock)
{
return false;
}
memset(&s_add, 0, sizeof(struct sockaddr_in));
s_add.sin_family=AF_INET;
s_add.sin_addr.s_addr=htonl(INADDR_ANY);
s_add.sin_port=htons(_clientPort);
setsockopt(_listenSock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
if(-1 == bind(_listenSock,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
{
return false;
}
if(-1 == listen(_listenSock,1))
{
return false;
}
qDebug()<<"listen "<<_clientPort;
return true;
}
void QFmClient::CheckRollBackData()
{
QString filename = qApp->applicationDirPath() + "/" + ROLL_BACK_FILE_NAME;
FILE *file = fopen(filename.toStdString().c_str(), "rb");
if (0 == file)
{//no data need to be roll back
return;
}
qDebug() << "need to roll back data...\r\n";
fseek(file, 0, SEEK_SET);
fseek(file, 0, SEEK_END);
int readLen = ftell(file);
fseek(file, 0, SEEK_SET);
memset(_codeBuf, 0, MAX_BUF_LEN);
int rlt = fread(_codeBuf, readLen, 1, file);
fclose(file);
if (1 != rlt || 0 >= readLen)
{
qDebug() << "roll back file error, file length error!\r\n";
remove(filename.toStdString().c_str());
return ;
}
memset(_sendbuf, 0, MAX_BUF_LEN);
ZH_decodeBkData(_codeBuf, _sendbuf, readLen);
//qDebug() << "rollback data:" << _sendbuf;
qDebug() << "\r\n";
QByteArray senddata(_sendbuf);
QJsonParseError json_error;
QJsonDocument doc = QJsonDocument::fromJson(senddata, &json_error);
if(json_error.error != QJsonParseError::NoError || !doc.isObject())
{
qDebug() << "error rbk json data!\r\n";
remove(filename.toStdString().c_str());
return ;
}
QJsonObject json = doc.object();
json["reqtype"] = 3;
AddReqCount(json);
memset(_sendbuf, 0, MAX_BUF_LEN);
QString temp = QString(QJsonDocument(json).toJson());
strcpy(_sendbuf, temp.toStdString().c_str());
qDebug() << "rollback data:" << _sendbuf;
qDebug() << "\r\n";
do
{
WaitAndSleep(5000);
if (0 != Try2ConnectZhProxy())
{
qDebug() << "roll back data: connect ZH Proxy failed, will try after 5 seconds...\r\n";
continue;
}
if (0 != SendCtrlInfo2Proxy())
{
qDebug() << "roll back data: send ctrl info 2 ZH Proxy failed, will try after 5 seconds...\r\n";
continue;
}
if (0 != SendData2ZhProxyAndWaitRspData())
{
qDebug() << "roll back data: send data to proxy fail, will try after 5 seconds...\r\n";
continue;
}
break;
}while(1);
qDebug() << "roll back ok!\r\n";
CloseSocket(&_zhProxySock);
remove(filename.toStdString().c_str());
return;
}
#ifndef QFMCLIENT_H
#define QFMCLIENT_H
#include <QThread>
#include <windows.h>
#include <QTextStream>
#define MAX_CODE_KEY 32
#define MAX_CTRL_INFO_LEN 16
#define MAX_BUF_LEN 4096
#define MAX_REQ_COUNT 25600
#define ROLL_BACK_FILE_NAME "fmclient.rbk"
class QFmClient : public QThread
{
Q_OBJECT
public:
QFmClient(QObject *parent = NULL);
void run();
void quit();
bool Init(QString proxy_IP, unsigned short proxy_port, unsigned short listen_prot, unsigned short long_timeout, unsigned short short_timeout);
signals:
void Error(QString error);
void HideUi();
void ShowUi();
private:
void CloseSocket(int *sock);
void GetKey();
bool StartListenport();
void CheckRollBackData();
int Try2ConnectZhProxy();
int SendCtrlInfo2Proxy();
void WaitAndSleep(int elapse);
bool WaitForConnectReqFromPos();
int ProcessPosReqData(QJsonObject& object);
void AddReqCount(QJsonObject &object);
int CheckIsCompleteJsonData(int *count, char *data);
int RecvSockData(int sock, char *buffer, int length);
int WaitAndReadDataFromPos(int type, int flag);
char *DecodeRecvData(char *buf, int length, int *dLength);
int UTF8ToGBK(unsigned char *lpUTF8Str, unsigned char *lpGBKStr, int nGBKStrLen);
int GBKToUTF8(unsigned char *lpGBKStr, int gbkLen, unsigned char *lpUTF8Str, int nUTF8StrLen);
int CheckReqFromPos(char *pJsonData, int dLength, int chkValue);
int SendSocketData(int sock, char *buf, int length, int flag);
char *EncodeSendData(char *buf, int length, int *eLength);
int SendData2ZhProxyAndWaitRspData();
int RecvAndCheckDataFromSock(int sock, int flag, int type);
int ProcessZhProxyRspDataAndSend2Pos();
int CheckRecvedData();
void BackupPosReq(char *req);
private:
bool _endflag;
char _recvbuf[MAX_BUF_LEN];
char _tempbuf[MAX_BUF_LEN];
char _sendbuf[MAX_BUF_LEN];
char _codeBuf[MAX_BUF_LEN];
unsigned char _codeKey[MAX_CODE_KEY];
//proxy IP
char _proxyIP[30];
//proxy 端口
unsigned short _proxyPort;
//QFMClient监听端口
unsigned short _clientPort;
//应用层分段大小(1024)
unsigned int _fmMSS;
//监听本地端口的socket
int _listenSock;
//接收pos请求的socket
int _acceptedSock;
//和proxy交互的socket
int _zhProxySock;
//接收数据长度
int _rcvLength;
//长超时
unsigned short _longTimeOut;
//短超时
unsigned short _shortTimeOut;
//当前使用超时
unsigned short _sockTimeOut;
char _keyLength;
char _curKeyPos;
char _codeFlag;
char _reserved;
static unsigned int s_reqCount;
};
#endif // QFMCLIENT_H
#include "widget.h"
#include "ui_widget.h"
#include <QPixmap>
#include <QPropertyAnimation>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowFlags(Qt::FramelessWindowHint);
this->setAttribute(Qt::WA_TranslucentBackground);
animation = new QPropertyAnimation(ui->label_wait_time_11, "pos");
animation->setStartValue(QPoint(0,1));
animation->setDuration(1000);
animation->setEndValue(QPoint(150,1));
animation->start();
QObject::connect(animation,SIGNAL(finished()),this,SLOT(move()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::move()
{
if(ui->label_wait_time_11->pos().x() == 0)
{
animation->setStartValue(QPoint(0,1));
animation->setDuration(1000);
animation->setEndValue(QPoint(150,1));
animation->start();
}
else
{
animation->setStartValue(QPoint(150,1));
animation->setDuration(1000);
animation->setEndValue(QPoint(0,1));
animation->start();
}
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPropertyAnimation>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected slots:
void move();
private:
Ui::Widget *ui;
QPropertyAnimation *animation;
};
#endif // WIDGET_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>310</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QWidget" name="horizontalWidget_17" native="true">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>310</width>
<height>310</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>310</width>
<height>310</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">/*
#widget_wait_main_11
{
border: 1px solid;
border-color: #FFD700;
}
*/
#widget_wait_time_11
{
border: 1px solid;
border-color: #FFD700;
border-radius: 10px;
}
#widget_wait_main_11
{
font: 9pt &quot;Agency FB&quot;;
background-color: rgb(255, 255, 255);
border-radius:15px
}
#label_wait_time_11
{
background-color:#32CD32;
border-radius: 10px;
min-width: 49px; min-height:23px;
max-width: 49px; max-height:23px;
}
#label_wait_msg_11
{
font: 75 16px &quot;Microsoft YaHei UI Light&quot;;
color: rgb(203, 203, 203);
color: rgb(160, 160, 160);
max-width: 310;
}
#label_wait_msg_time_11
{
font: 16px &quot;微软雅黑&quot;;
}
#label_wait_title_11
{
font: 75 25px &quot;Microsoft YaHei UI Light&quot;;
}
#btn_wait_quit_11
{
border:0px;
border-radius:3px;
background-color: rgb(128, 134, 143);
font: 75 20px &quot;Microsoft YaHei UI Light&quot;;
color: rgb(255, 255, 255);
}</string>
</property>
<property name="locale">
<locale language="Chinese" country="China"/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_36">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_93">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget_wait_main_11" native="true">
<property name="minimumSize">
<size>
<width>310</width>
<height>310</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>310</width>
<height>310</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_74">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_wait_title_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">#label_wait_title
{
font: 75 25px &quot;Microsoft YaHei UI Light&quot;;
}</string>
</property>
<property name="text">
<string>扫描成功 正在支付中</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_75">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_wait_msg_11">
<property name="styleSheet">
<string notr="true">#label_wait_msg
{
font: 75 16px &quot;Microsoft YaHei UI Light&quot;;
color: rgb(203, 203, 203);
color: rgb(160, 160, 160);
max-width: 310;
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_76">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="horizontalWidget_18" native="true">
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_37">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_94">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget_wait_time_11" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>25</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">#Widget
{
border: 1px solid #FF00FF;
border-radius: 5px;
}</string>
</property>
<widget class="QLabel" name="label_wait_time_11">
<property name="geometry">
<rect>
<x>1</x>
<y>1</y>
<width>49</width>
<height>23</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>49</width>
<height>23</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>49</width>
<height>23</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">#label_wait_time
{
font: 16px &quot;微软雅黑&quot;;
color: rgb(0, 179, 238);
min-width: 64px; min-height:64px;
max-width: 64px; max-height:64px;
}
</string>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_95">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_77">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_wait_msg_time_11">
<property name="styleSheet">
<string notr="true">#label_wait_msg_time
{
font: 16px &quot;微软雅黑&quot;;
}
</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_78">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_38">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_96">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<spacer name="horizontalSpacer_97">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_79">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_98">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment