FXSend/QQTX/QQTX.cpp
2025-02-28 17:05:50 +08:00

884 lines
20 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// QQTX.cpp: implementation of the CQQTX class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "QQTX.h"
/*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include "..\..\..\public\md53\\md5_L.h"
CQQTX::CQQTX()
{
m_hSocket = INVALID_SOCKET;
memset( m_szIP , 0 , sizeof(m_szIP) );
m_lPort = 0;
m_bQuitThread = false;
m_dwEndSendTime = 0;
m_dwEndRecvTime = 0;
m_dwTestCount = 0;
m_bRecvFrame = false;
m_lID = 1;
m_pRecvProc = NULL;
m_bConnect = false;
m_bLoginQQTX= -1;
m_bInitQQTX = false;
memset(m_szQQTXIP ,0,sizeof(m_szQQTXIP));
memset(m_szQQTXUser ,0,sizeof(m_szQQTXUser));
memset(m_szQQTXPasswd,0,sizeof(m_szQQTXPasswd));
memset(m_szQQTXKey ,0,sizeof(m_szQQTXKey));
m_lConnectType = 2; //默认是接收与发送类型
WSADATA wsaData; //用于初始化socket的结构
//以下为初始化SOCKET环境
int iTemp=WSAStartup(0x0101,&wsaData); //初始化socket环境
InitializeCriticalSection(&m_CriDeliverList);
InitializeCriticalSection(&m_CriErrMsg);
InitializeCriticalSection(&m_CriSendFrame);
//定义队列
m_lSendID = 1;
m_pDeliverList = new QQTX_Deliver_List[QQTX_MAX_DELIVER];
m_lDeliverList=0;
for ( int i=0 ; i<QQTX_MAX_DELIVER ; i++ )
{
m_pDeliverList[i].lSendID = 0;
}
m_dwEndSocketSendTime = 0;
m_lSendInterval = 0;
m_hThread = INVALID_HANDLE_VALUE;
m_hThread_Send = INVALID_HANDLE_VALUE;
}
CQQTX::~CQQTX()
{
Stop();
//删除数据
if ( m_pDeliverList )
{delete [] m_pDeliverList;m_pDeliverList=NULL;}
DeleteCriticalSection(&m_CriDeliverList);
DeleteCriticalSection(&m_CriErrMsg);
DeleteCriticalSection(&m_CriSendFrame);
//退出Socket
WSACleanup();
}
BOOL CQQTX::Connect(const char *pAddr, long lPort, BOOL bReConnect)
{
if ( !bReConnect && m_hSocket!=INVALID_SOCKET) //已连接,并且无需重连
{
return true;
}
this->Stop(); //重新连接,先让原来的线程停止
strcpy( m_szIP,pAddr );
m_lPort = lPort;
sockaddr_in sAddr;
m_hSocket=socket(AF_INET,SOCK_STREAM,0);
sAddr.sin_family=AF_INET;
sAddr.sin_port=0;
sAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
return false;
}
sAddr.sin_port=htons((unsigned short)lPort);
sAddr.sin_addr.s_addr=inet_addr(pAddr);
if (sAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(pAddr);
if (lphost != NULL)
sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
Close();
return false;
}
}
if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
Close();
return false;
}
//设置Socket
u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET
//u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET
ioctlsocket( m_hSocket,FIONBIO,&ulTemp );
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
m_bQuitThread = false;
DWORD dwTemp;
HANDLE m_hThread=CreateThread(NULL,0,SocketRecv,(LPVOID)this,0,&dwTemp);
// if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) )
if ( m_hThread == INVALID_HANDLE_VALUE )
{
Close();
return false;
}
HANDLE m_hThread_Send=CreateThread(NULL,0,SocketSend,(LPVOID)this,0,&dwTemp);
// if ( !::AfxBeginThread((AFX_THREADPROC)CNetSocket::SocketRecv,(LPVOID)this,THREAD_PRIORITY_LOWEST) )
if ( m_hThread_Send == INVALID_HANDLE_VALUE )
{
Close();
return false;
}
//SetThreadPriority(m_hThread,THREAD_PRIORITY_LOWEST); //设置优先级
m_bConnect = true;
return true;
}
BOOL CQQTX::Connect2()
{
sockaddr_in sAddr;
m_hSocket=socket(AF_INET,SOCK_STREAM,0);
sAddr.sin_family=AF_INET;
sAddr.sin_port=0;
sAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
return false;
}
sAddr.sin_port=htons((unsigned short)m_lPort);
sAddr.sin_addr.s_addr=inet_addr(m_szIP);
if (sAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(m_szIP);
if (lphost != NULL)
sAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
Close();
return false;
}
}
if (connect(m_hSocket,(LPSOCKADDR)&sAddr,sizeof(sAddr))==SOCKET_ERROR)
{
Close();
return false;
}
//设置Socket
u_long ulTemp=1; //将SOCKET设成非阻塞式的SOCKET
//u_long ulTemp=0; //将SOCKET设成阻塞式的SOCKET
ioctlsocket( m_hSocket,FIONBIO,&ulTemp );
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_SNDBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
ulTemp=1024000;
setsockopt( m_hSocket , SOL_SOCKET, SO_RCVBUF ,(const char *)&ulTemp ,sizeof(ulTemp)); //设绶冲
return true;
}
BOOL CQQTX::isConnect()
{
return m_bConnect;
}
void CQQTX::Stop()
{
m_bQuitThread = true;
if (m_hThread != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread,2000) == WAIT_TIMEOUT ) //等待5秒让线程退出
{
TerminateThread(m_hThread,0); //如果退出超时,强制结束线程
}
m_hThread = INVALID_HANDLE_VALUE;
if (m_hThread_Send != INVALID_HANDLE_VALUE && WaitForSingleObject(m_hThread_Send,2000) == WAIT_TIMEOUT ) //等待5秒让线程退出
{
TerminateThread(m_hThread_Send,0); //如果退出超时,强制结束线程
}
m_hThread_Send = INVALID_HANDLE_VALUE;
Close();
}
BOOL CQQTX::isSocketClose(SOCKET s)
{
BOOL bConnDropped = FALSE;
INT iRet = 0;
BOOL bOK = TRUE;
if (s == INVALID_SOCKET)
return TRUE;
struct timeval timeout = { 0, 0 };
fd_set readSocketSet;
FD_ZERO(&readSocketSet);
FD_SET(s, &readSocketSet);
iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
bOK = (iRet > 0);
if(bOK)
{
bOK = FD_ISSET(s, &readSocketSet);
}
if(bOK)
{
CHAR szBuffer[1] = "";
iRet = recv(s, szBuffer, 1, MSG_PEEK);
bOK = (iRet > 0);
if(!bOK)
{
INT iError = WSAGetLastError();
bConnDropped = (( iError == WSAENETRESET) ||
(iError == WSAECONNABORTED) ||
(iError == WSAECONNRESET) ||
(iError == WSAEINVAL) ||
(iRet == 0));
}
}
return(bConnDropped);
}
void CQQTX::Close()
{
if ( m_hSocket == INVALID_SOCKET )
return;
if ( m_hSocket != INVALID_SOCKET )
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
m_bConnect = false;
//m_dwEndSendTime=0;
//m_dwEndRecvTime=0;
}
long CQQTX::Send(SOCKET sock,BYTE *pData, long lLen)
{
#define SOCKET_SEND_TIMEOUT 10000 //10秒发送超时
if ( sock == INVALID_SOCKET )
return 0;
long lSended = 0;
DWORD lTimeOut = ::GetTickCount();
while ( 1 )
{
long lRet = send(sock,(char*)(pData+lSended), lLen-lSended,0);
if ( lRet == SOCKET_ERROR ) //发送错误
{
if ( GetLastError() != WSAEWOULDBLOCK ) //绶区已满
return SOCKET_ERROR;
}
if ( lRet > 0 )
{
lSended += lRet;
if ( lSended >= lLen )
break;
}
else
{
Sleep_Lu( 20 ); //绶冲区已满,稍等
}
if ( ::GetTickCount() - lTimeOut > SOCKET_SEND_TIMEOUT )
break;
}
return lSended;
}
DWORD WINAPI CQQTX::SocketSend(LPVOID lParam)
{
CQQTX * pNet = (CQQTX *)lParam;
QQTX_Data_Recv Drecv={0};
while ( !pNet->m_bQuitThread )
{
//发送短信
Sleep_Lu(20);
}
return 1;
}
DWORD WINAPI CQQTX::SocketRecv(LPVOID lParam)
{
CQQTX * pNet = (CQQTX *)lParam;
QQTX_Data_Recv Drecv={0};
pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
DWORD dwEndSend=GetTickCount();
while ( !pNet->m_bQuitThread )
{
BOOL bReConnect=false;
if ( isSocketClose(pNet->m_hSocket) )
{
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
if ( pNet->m_bInitQQTX ) //原已连接的,重新连接
{
bReConnect = true;
}
else
{
pNet->m_bLoginQQTX = -4; //对端断开连接,登录失败
}
}
if ( ReadFrame(pNet->m_hSocket,&Drecv) ) //判断是否有接收到新的Frame
{
pNet->m_dwEndRecvTime = ::GetTickCount(); //保存最后接收到帧的时间
pNet->m_bRecvFrame = true;
pNet->RecvFrame(Drecv); //处理接收到的帧
Drecv.lDataLen = 0;
Drecv.lRecvType = 0;
if ( Drecv.pRecvFrame )
{
delete Drecv.pRecvFrame;
Drecv.pRecvFrame = NULL;
}
}
//判断接收是否超时
//if ( pNet->m_dwEndSendTime > 0 && !pNet->m_bRecvFrame)
if ( pNet->m_dwEndSendTime>0 && ::GetTickCount() - pNet->m_dwEndRecvTime >(QQTX_ACTIVE_TESTTIME*QQTX_ACTIVE_COUNTOUT+QQTX_ACTIVE_TIMEOUT) ) //接收超时
{
pNet->m_dwEndRecvTime = ::GetTickCount()-QQTX_ACTIVE_TIMEOUT; //如果接收超时,重新计数
pNet->Close();
//重新接收数据
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
memset(&Drecv,0,sizeof(Drecv));
bReConnect = true;
}
//判断是否应该发送Active_Test指令
if ( pNet->m_dwEndSendTime > 0 )
{
if ( ::GetTickCount() - pNet->m_dwEndSendTime > QQTX_ACTIVE_TESTTIME ) //重新连接
{
ULONG lSeq=0;
pNet->SendFrame(pNet->m_hSocket,pNet->m_lID,pNet->m_dwEndSendTime, QQ_ACTIVE_TEST ,_T(""),lSeq );
}
}
//发送短信
//pNet->Back_Send();
if ( bReConnect )
{
for ( int i=0 ; i<30 && !pNet->m_bQuitThread; i++ ) //延时5秒
{
Sleep_Lu(100);
}
pNet->SetErrMsg("QQTX消息:正在重连网关...");
if ( !pNet->m_bQuitThread )
pNet->InitQQTX2(); //重新连接到服务器
}
//Sleep_Lu(1);
}
if ( Drecv.pRecvFrame )
delete Drecv.pRecvFrame;
pNet->Close();
return 1;
}
void CQQTX::SetRecvProc(QQTX_RECVPROC proc)
{
m_pRecvProc = proc;
}
BOOL CQQTX::ReadFrame(SOCKET s, QQTX_Data_Recv *pRecv)
{
ULONG nBytes=0;
ioctlsocket(s,FIONREAD, &nBytes);
if (nBytes <= 0 )
{
Sleep_Lu(20); //没有数据,等待一段时间
return false;
}
BYTE bTemp=0;
long lRet=0;
switch( pRecv->lRecvType )
{
case 0://接收头
lRet = recv(s, (char*)&bTemp,sizeof(bTemp),0);
if ( lRet > 0 && bTemp==QQ_stx)
{
pRecv->lRecvType = 1; //开始接收长度
pRecv->lDataLen = 0;
if ( pRecv->pRecvFrame )
{
delete pRecv->pRecvFrame;
pRecv->pRecvFrame = NULL;
}
}
break;
case 1: //接收长度
lRet = recv(s, (char*)&pRecv->lDataLen,sizeof(pRecv->lDataLen),0);
if ( lRet > 0 )
{
pRecv->lDataLen = ntohl(pRecv->lDataLen);
if ( pRecv->lDataLen > 0 && pRecv->lDataLen<4096000)
{
pRecv->pRecvFrame = new BYTE[pRecv->lDataLen];
*((BYTE*)pRecv->pRecvFrame) = QQ_stx; //存好前4个字节
*((ULONG*)(pRecv->pRecvFrame+1)) = pRecv->lDataLen; //存好前4个字节
pRecv->lRecvLen = sizeof(pRecv->lDataLen)+1;
pRecv->lRecvType = 2; //开始接收数据s
}
}
break;
case 2: //接收数据
{
//计算需要接收的总字节数
ULONG lBeRecv = pRecv->lDataLen-pRecv->lRecvLen;
lRet = recv(s,(char*)pRecv->pRecvFrame+pRecv->lRecvLen , lBeRecv ,0);
if ( lRet > 0 )
pRecv->lRecvLen += lRet ;
if ( pRecv->lRecvLen == pRecv->lDataLen ) //Frame 已收满
{
pRecv->lDataLen = 0; //重新开始接收
return true;
}
}
break;
}
/*
if ( pRecv->lDataLen <= 0 && nBytes<= sizeof(pRecv->lDataLen) ) //未收够长度信息
return false;
long lRet;
if (pRecv->lDataLen <= 0 ) //未收到数据,现在开始接收
{
lRet = recv(s, (char*)&pRecv->lDataLen,sizeof(pRecv->lDataLen),0);
if ( lRet > 0 )
{
pRecv->lDataLen = ntohl(pRecv->lDataLen);
if ( pRecv->lDataLen > 0 )
{
if ( pRecv->pRecvFrame )
{
delete pRecv->pRecvFrame;
pRecv->pRecvFrame = NULL;
}
pRecv->pRecvFrame = new BYTE[pRecv->lDataLen];
*((long*)pRecv->pRecvFrame) = pRecv->lDataLen; //存好前4个字节
pRecv->lRecvLen = sizeof(pRecv->lDataLen);
}
}
}
else
{
//计算需要接收的总字节数
ULONG lBeRecv = pRecv->lDataLen-pRecv->lRecvLen;
lRet = recv(s,(char*)pRecv->pRecvFrame+pRecv->lRecvLen , lBeRecv ,0);
if ( lRet > 0 )
pRecv->lRecvLen += lRet ;
if ( pRecv->lRecvLen == pRecv->lDataLen ) //Frame 已收满
{
pRecv->lDataLen = 0; //重新开始接收
return true;
}
}
*/
return false;
}
BOOL CQQTX::RecvFrame(QQTX_Data_Recv &Drecv)
{
QQTX_Head * pHead=(QQTX_Head *)Drecv.pRecvFrame;
if ( pHead->Total_Length != Drecv.lRecvLen )
return false;
pHead->Command_Id = ntohl(pHead->Command_Id);
pHead->Sequence_Id= ntohl(pHead->Sequence_Id);
BYTE * pData = (BYTE*)(Drecv.pRecvFrame+sizeof(QQTX_Head));
long lLen = pHead->Total_Length-sizeof(QQTX_Head)-1;
CStringA strAnsA((char*)pData,lLen);
CString strAns = CA2W(strAnsA,CP_UTF8);
long lRet = 0;
switch( pHead->Command_Id )
{
case QQ_CONNECT_RESP:
lRet = Process_Connect(*pHead,strAns);
break;
case QQ_ACTIVE_TEST_RESP:
lRet = Process_Active(*pHead,strAns);
break;
default:
lRet = Process_Other(*pHead,strAns);
break;
}
return lRet;
}
long CQQTX::QQTX_Init(const TCHAR *pIP,USHORT lPort, const TCHAR *pUser, const TCHAR *pPasswd,const TCHAR * pKey,int lConnectType)
{
//记录信息
strcpy(m_szQQTXIP,CW2A(pIP));
_tcscpy(m_szQQTXUser,pUser);
_tcscpy(m_szQQTXPasswd,pPasswd);
_tcscpy(m_szQQTXKey,pKey);
m_lConnectType = lConnectType;
if ( !Connect(m_szQQTXIP,lPort) )
{
return -1; //连接服务器失败
}
CString strReq;
CString strTemp=_T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")\
_T("<Req>")\
_T("<ConnectType>%d</ConnectType>")\
_T("<UserName>%s</UserName>")\
_T("<TimeStamp>%s</TimeStamp>")\
_T("<Password>%s</Password>")\
_T("</Req>");
CString strTimeStamp;
SYSTEMTIME t;GetLocalTime(&t);
strTimeStamp.Format(_T("%04d%02d%02d%02d%02d%02d"),t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
CString strUserName = m_szQQTXUser;
CString strPasswd = m_szQQTXPasswd;
CString strKey = m_szQQTXKey;
CString strMd5=CSendPub::GetMD5(strUserName+strKey+strTimeStamp+strPasswd);
strReq.Format(strTemp,m_lConnectType,strUserName,strTimeStamp,strMd5);
m_bLoginQQTX = -1;
ULONG lSeq=0;
if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,QQ_CONNECT,strReq,lSeq) )
{
m_bQuitThread = true;
return -2; //发送数据失败
}
long lTime = ::GetTickCount();
while ( m_bLoginQQTX == -1 )
{
if ( ::GetTickCount()-lTime > 30000 ) //超时了
break;
Sleep_Lu(20);
}
if ( m_bLoginQQTX==0 )
{
m_bInitQQTX = true; //已初始化
return m_bLoginQQTX; //返回成功
}
if ( m_bLoginQQTX == -1 )
{
m_bQuitThread = true;
return -3; //登录超时
}
else
{
m_bQuitThread = true;
return m_bLoginQQTX; //登录返回成功,具体请看错误码
}
m_bQuitThread = true;
return -4; //其它错误
}
long CQQTX::SendFrame(SOCKET sock,ULONG &lID,DWORD &dwEndSendTime,ULONG lCommandID,CString strReq,ULONG & lSeq )
{
EnterCriticalSection(&m_CriSendFrame); //防止冲突
CStringA strReqA = CW2A(strReq,CP_UTF8);
long lDataLen = strReqA.GetLength();
QQTX_Head head={0};
long lAllLen;
head.Total_Length = sizeof(head)+lDataLen+1; //总长度最后还有个etx
lAllLen = head.Total_Length;
head.Command_Id = lCommandID;
if ( lID >= 0xF000000 ) //重新开始序号
lID = 1;
if ( lSeq > 0 )
head.Sequence_Id = lSeq; //直接使用相同序号的发送
else
head.Sequence_Id = lID++;
lSeq = head.Sequence_Id; //返回
head.stx = QQ_stx;
head.Total_Length = htonl(head.Total_Length);
head.Command_Id = htonl(head.Command_Id);
head.Sequence_Id = htonl(head.Sequence_Id);
dwEndSendTime = ::GetTickCount(); //记录最后发送时间
BYTE * pSData = new BYTE[lAllLen];
long lSetLen=0;
memcpy(pSData,&head,sizeof(head));lSetLen+=sizeof(head);
memcpy(pSData+lSetLen,strReqA.GetBuffer(),lDataLen);lSetLen+=lDataLen;
pSData[lSetLen]=QQ_etx;lSetLen+=1;
BOOL bOK = Send(sock,(BYTE*)pSData , lAllLen );
delete pSData;
long lRet = 0;
if ( bOK )
lRet = head.Sequence_Id;
LeaveCriticalSection(&m_CriSendFrame); //防止冲突
return lRet;
}
long CQQTX::Process_Connect(QQTX_Head head,CString strAns)
{
CMarkup xml(strAns);
CString strRetCode;
CString strErrMsg;
if ( xml.FindElem(_T("/Ans/RetCode")) )
strRetCode =xml.GetData();
if ( xml.FindElem(_T("/Ans/ErrMsg")) )
strErrMsg =xml.GetData();
BOOL bLoginRet = false;
strRetCode.Trim();
if ( strRetCode == CString(_T("0")) )
{
bLoginRet = true;
}
if ( m_bInitQQTX && !bLoginRet ) //需要重新登录
{
//InitQQTX2();
//登录不成功,关闭连接
this->Close();
}
CString str;
str.Format(_T("QQTX消息:连接网关返回代码:%s,%s") , strRetCode,strErrMsg );
SetErrMsg(str);
m_bLoginQQTX = _ttol(strRetCode);
if (!bLoginRet )
m_bLoginQQTX = -100;
return 1;
}
BOOL CQQTX::InitQQTX2()
{
m_bLoginQQTX = -1;
if ( !Connect2() )
{
return false; //连接服务器失败
}
CString strReq;
CString strTemp=_T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")\
_T("<Req>")\
_T("<ConnectType>%d</ConnectType>")\
_T("<UserName>%s</UserName>")\
_T("<TimeStamp>%s</TimeStamp>")\
_T("<Password>%s</Password>")\
_T("</Req>");
CString strTimeStamp;
SYSTEMTIME t;GetLocalTime(&t);
strTimeStamp.Format(_T("%04d%02d%02d%02d%02d%02d"),t.wYear,t.wMonth,t.wDay,t.wHour,t.wMinute,t.wSecond);
CString strUserName = m_szQQTXUser;
CString strPasswd = m_szQQTXPasswd;
CString strKey = m_szQQTXKey;
CString strMd5=CSendPub::GetMD5(strUserName+strKey+strTimeStamp+strPasswd);
strReq.Format(strTemp,m_lConnectType,strUserName,strTimeStamp,strMd5);
m_bLoginQQTX = -1;
ULONG lSeq=0;
if ( !SendFrame(m_hSocket,m_lID,m_dwEndSendTime,QQ_CONNECT,strReq,lSeq) )
return -2; //发送数据失败
//重新连接时,需要重发短信
// memset(m_pSendList,0,sizeof(QQTX_Send_List)*SMS_MAX_LIST);
/*
for ( int i=0 ; i< SMS_MAX_LIST ;i++ )
{
if ( m_pSendList[i].lSendID > 0 )
{
m_pSendList[i].lReSendCount = 0;
m_pSendList[i].lSendTime = 0;
m_pSendList[i].lSeq = 0;
}
}
*/
return -4; //其它错误
}
long CQQTX::Process_Active(QQTX_Head head, CString strAns)
{
m_dwTestCount = 0; //收到active指令检测次数为0
return 1;
}
long CQQTX::Process_Other(QQTX_Head head,CString strAns)
{
QQTX_Deliver_List Deliver;
Deliver.lSendID = head.Sequence_Id;
Deliver.head = head;
Deliver.strAns = strAns;
Deliver_Add(Deliver); //添加到列表
/*
//发送返回
QQTX_Deliver_Resp resp={0};
resp.Msg_ID = pDeliver->Msg_ID;
resp.Result = 0;
ULONG lReq=head.Sequence_Id;
SendFrame(m_hSocket,m_lID,m_dwEndSendTime,QQTX_DELIVER_RESP,(BYTE*)&resp,lReq);
*/
return true;
}
BOOL CQQTX::GetDeliver(QQTX_Deliver_List &deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
for ( int i=m_lDeliverList ; i< QQTX_MAX_DELIVER; i++ )
{
if ( m_pDeliverList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lDeliverList = i+1;
deliver = m_pDeliverList[i];
m_pDeliverList[i].lSendID = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lDeliverList; i++ )
{
if ( m_pDeliverList[i].lSendID != 0 ) //其等于0时认为此位置为空
{
m_lDeliverList = i+1;
deliver = m_pDeliverList[i];
m_pDeliverList[i].lSendID = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
m_lDeliverList = 0;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
BOOL CQQTX::QQTX_Exit()
{
m_bInitQQTX = false; //已初始化
//ULONG lSeq=0;
//SendFrame(m_hSocket,m_lID,m_dwEndSendTime,QQTX_TERMINATE,_T(""),lSeq);
Stop(); //停止
return true;
}
BOOL CQQTX::Deliver_Add(QQTX_Deliver_List Deliver)
{
EnterCriticalSection(&m_CriDeliverList); //防止冲突
//从当前点到结尾
for ( int i=m_lDeliverList ; i< QQTX_MAX_DELIVER; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
//从开头到当前点
for ( i=0 ; i<m_lDeliverList; i++ )
{
if ( m_pDeliverList[i].lSendID == 0 ) //其等于0时认为此位置为空
{
m_pDeliverList[i] = Deliver;
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return true;
}
}
LeaveCriticalSection(&m_CriDeliverList); //防止冲突
return false;
}
void CQQTX::SetSendSpeed(long lSpeed)
{
if ( lSpeed<=0 )
m_lSendInterval = 0;
else
m_lSendInterval = 1000/lSpeed;
}
long CQQTX::GetWFSms()
{
long lWF=0;
return lWF;
}
long CQQTX::GetReportSms()
{
long lReport=0;
return lReport;
}
CString CQQTX::GetErrMsg()
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
CString strRet;
if ( m_strErrMsg.GetLength()>0 )
{
strRet = m_strErrMsg;
m_strErrMsg = CString(_T(""));
}
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
return strRet;
}
void CQQTX::SetErrMsg(CString str)
{
EnterCriticalSection(&m_CriErrMsg); //防止冲突
m_strErrMsg = str;
LeaveCriticalSection(&m_CriErrMsg); //防止冲突
}
BOOL CQQTX::isConnectGateWay()
{
if ( m_bLoginQQTX == 0 )
{
return true;
}
return false;
}