929 lines
22 KiB
C++
929 lines
22 KiB
C++
// processsocket.cpp : implementation file
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "CorpSms.h"
|
||
#include "processsocket.h"
|
||
|
||
#ifdef _DEBUG
|
||
#define new DEBUG_NEW
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[] = __FILE__;
|
||
#endif
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CProcessSocket
|
||
|
||
#include "..\public\pop3\pop3.h"
|
||
#ifdef _M_X64
|
||
#include "..\public\lzo_64\Lzo.cpp"
|
||
#else
|
||
#include "..\public\lzo\Lzo.cpp"
|
||
#endif
|
||
|
||
|
||
#define ZLIB_WINAPI
|
||
#include "..\public\zlib\zlib.h"
|
||
#ifdef _M_X64
|
||
#pragma comment(lib,"..\\public\\zlib\\Lib64\\zlibwapi.lib")
|
||
#else
|
||
#pragma comment(lib,"..\\public\\zlib\\Lib\\zlibwapi.lib")
|
||
#endif
|
||
|
||
CProcessSocket::CProcessSocket()
|
||
{
|
||
m_pWnd = NULL;
|
||
m_bSend = false;
|
||
m_bConnect = false;
|
||
m_lID = 0; //发送帧的ID,由0开始
|
||
|
||
memset(&m_RecvHead,0,sizeof(m_RecvHead)); //用于接收Head
|
||
m_lRecvHead = 0; //已收到的Head字节数
|
||
m_lRecvFrame= 0; //已收到的Frame字节数
|
||
m_bRecvFrame= false; //开始时不是在收Frame;
|
||
m_pRecvFrame= NULL;
|
||
memset(&m_Setup,0,sizeof(m_Setup));
|
||
m_lUserID = 0;
|
||
|
||
//超透网关用到
|
||
m_hInternet = NULL;
|
||
m_hConnection = NULL;
|
||
|
||
m_lCompress = SENDDATA_COMPRESS;
|
||
|
||
m_hHttp = INVALID_HANDLE_VALUE;
|
||
}
|
||
|
||
CProcessSocket::~CProcessSocket()
|
||
{
|
||
Close();
|
||
}
|
||
|
||
|
||
// Do not edit the following lines, which are needed by ClassWizard.
|
||
#if 0
|
||
BEGIN_MESSAGE_MAP(CProcessSocket, CAsyncSocket)
|
||
//{{AFX_MSG_MAP(CProcessSocket)
|
||
//}}AFX_MSG_MAP
|
||
END_MESSAGE_MAP()
|
||
#endif // 0
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CProcessSocket member functions
|
||
|
||
void CProcessSocket::OnConnect(int nErrorCode)
|
||
{
|
||
CAsyncProxySocket::OnConnect(nErrorCode);
|
||
if (nErrorCode)
|
||
{
|
||
m_bSend = false;
|
||
this->Close();
|
||
NotifyMainWnd( PROCESSSOCKET_ERROR , PROCESSSOCKET_ERROR_CONNECT , 0 );
|
||
}
|
||
else
|
||
{
|
||
m_bSend = true;
|
||
}
|
||
}
|
||
|
||
void CProcessSocket::OnSend(int nErrorCode)
|
||
{
|
||
CAsyncProxySocket::OnSend(nErrorCode);
|
||
|
||
//发送队列中的内容
|
||
while (!m_Frame.IsEmpty())
|
||
{
|
||
Socket_Head * pHead = m_Frame.GetHead();
|
||
ULONG lSendFrameLen = pHead->lFrameLen; //最终需要发送的长度
|
||
BOOL bOK = true;
|
||
m_Frame.RemoveHead();
|
||
if ( pHead->bCompress >0 )
|
||
{
|
||
bOK = false;
|
||
ULONG lCount = pHead->lFrameLen + 2048;
|
||
BYTE * pFrame = new BYTE[lCount];memset(pFrame , 0 , lCount);
|
||
if ( pHead->bCompress == 1 )
|
||
{
|
||
if ( lzo.Compress( pHead->pFrame , pHead->lFrameLen , pFrame , &lCount )>0 && lCount > 0 )
|
||
{
|
||
bOK = true;
|
||
}
|
||
}
|
||
if ( pHead->bCompress == 2 )
|
||
{
|
||
if ( compress( pFrame , &lCount , pHead->pFrame , pHead->lFrameLen )==Z_OK && lCount > 0 )
|
||
{
|
||
bOK = true;
|
||
}
|
||
}
|
||
if ( bOK )
|
||
{
|
||
delete pHead->pFrame; //压缩成功,替换要发送的内容
|
||
pHead->pFrame = pFrame;
|
||
pHead->lCompressLen = lCount;
|
||
lSendFrameLen = lCount; //最终要发送的字节数
|
||
}
|
||
else
|
||
{
|
||
delete pFrame;
|
||
}
|
||
}
|
||
if ( bOK )
|
||
{
|
||
Send( pHead , sizeof(Socket_Head) );
|
||
if ( lSendFrameLen>0 )
|
||
Send( pHead->pFrame , lSendFrameLen );
|
||
}
|
||
delete pHead->pFrame;
|
||
delete pHead;
|
||
}
|
||
}
|
||
|
||
void CProcessSocket::OnClose(int nErrorCode)
|
||
{
|
||
CAsyncProxySocket::OnClose(nErrorCode);
|
||
Close();
|
||
// AfxMessageBox( "close" );
|
||
}
|
||
|
||
void CProcessSocket::OnReceive(int nErrorCode)
|
||
{
|
||
CAsyncProxySocket::OnReceive(nErrorCode);
|
||
|
||
for(;;)
|
||
{
|
||
long lRet;
|
||
if (m_bRecvFrame)
|
||
{
|
||
//计算需要接收的总字节数
|
||
ULONG lBeRecv = m_RecvHead.lFrameLen;
|
||
if ( m_RecvHead.bCompress>0 )
|
||
lBeRecv=m_RecvHead.lCompressLen;
|
||
|
||
lRet = Receive( m_pRecvFrame+m_lRecvFrame , lBeRecv-m_lRecvFrame );
|
||
if ( lRet > 0 )
|
||
m_lRecvFrame += lRet ;
|
||
if ( lBeRecv == m_lRecvFrame ) //Frame 已收满
|
||
{
|
||
BYTE * pFrame = m_pRecvFrame;
|
||
BOOL bOK = true;
|
||
if ( m_RecvHead.lFuncType != SMSFUNC_TEST )
|
||
SetCompressType(m_RecvHead.bCompress); //取来自服务器的压缩选项
|
||
if ( m_RecvHead.bCompress>0 ) //解压
|
||
{
|
||
ULONG lCount = m_RecvHead.lFrameLen+2048;
|
||
pFrame = new BYTE[lCount];memset( pFrame , 0 , lCount );
|
||
if ( m_RecvHead.bCompress == 1 )
|
||
{
|
||
if ( !lzo.decompress( m_pRecvFrame , m_lRecvFrame , pFrame , &lCount ))
|
||
{
|
||
bOK = false; //解压不成功,不用通知收到帧
|
||
//解压不成功
|
||
delete pFrame;
|
||
}
|
||
}
|
||
if ( m_RecvHead.bCompress == 2 )
|
||
{
|
||
if ( uncompress( pFrame , &lCount , m_pRecvFrame , m_lRecvFrame)!=Z_OK)
|
||
{
|
||
bOK = false; //解压不成功,不用通知收到帧
|
||
//解压不成功
|
||
delete pFrame;
|
||
}
|
||
}
|
||
|
||
delete m_pRecvFrame; //因为数据已转换为pFrame,所以要删除m_pRecvFrame;
|
||
m_pRecvFrame = NULL;
|
||
}
|
||
else
|
||
{
|
||
m_pRecvFrame = NULL; //因为处理PROCESSSOCKET_FRAME会delete,所以现在只需置其等于NULL即可
|
||
}
|
||
if ( bOK )
|
||
{
|
||
Socket_Head * pHead = new Socket_Head;
|
||
*pHead = m_RecvHead;
|
||
pHead->pFrame = pFrame;
|
||
NotifyMainWnd( PROCESSSOCKET_FRAME , (WPARAM)pHead , 0 );
|
||
}
|
||
m_bRecvFrame = false; //又再需要接收头
|
||
m_lRecvHead = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lRet = Receive( ((BYTE*)&m_RecvHead)+m_lRecvHead,sizeof(m_RecvHead)-m_lRecvHead );
|
||
if ( lRet > 0 )
|
||
m_lRecvHead += lRet;
|
||
if ( m_lRecvHead == sizeof(m_RecvHead) ) //头已收满
|
||
{
|
||
if ( m_pRecvFrame )
|
||
delete m_pRecvFrame;
|
||
if ( m_RecvHead.bCompress>0 )
|
||
m_pRecvFrame = new BYTE[m_RecvHead.lCompressLen];
|
||
else
|
||
m_pRecvFrame = new BYTE[m_RecvHead.lFrameLen];
|
||
m_bRecvFrame = true; //下一次需要收Frame了
|
||
m_lRecvFrame = 0; //收到的Frame 字节数为0
|
||
}
|
||
}
|
||
if (lRet==SOCKET_ERROR || !lRet)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CProcessSocket::OnProxyOperationFailed(int nOpID)
|
||
{
|
||
NotifyMainWnd( PROCESSSOCKET_ERROR , PROCESSSOCKET_ERROR_PROXY , 0 );
|
||
}
|
||
void CProcessSocket::OnListenFinished(unsigned long &retProxyIp,int &retProxyPort)
|
||
{
|
||
}
|
||
|
||
void CProcessSocket::SetParent(CWnd *pWnd)
|
||
{
|
||
m_pWnd = pWnd;
|
||
}
|
||
|
||
BOOL CProcessSocket::ConnectToServer(SM_Setup setup,BOOL bReConnect)
|
||
{
|
||
//判断Socket原先有没有打开,如果打开
|
||
if ( m_bConnect )
|
||
{
|
||
if ( bReConnect )
|
||
{
|
||
Close();
|
||
}
|
||
else
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
//不管什么情况,关掉连接再说
|
||
this->Close();
|
||
m_Setup = setup; //取得参数
|
||
|
||
if ( m_Setup.bGateWay ) //使用超透网关
|
||
{
|
||
/*
|
||
HTTP:
|
||
HTTP=HTTP://proxyserver:port
|
||
FTP:
|
||
FTP:FTP://proxyserver:port
|
||
GOPHER
|
||
GOPHER=HTTP://proxyserver:port
|
||
SOCKS=proxyserver:port
|
||
*/
|
||
CString strTemp;
|
||
CString strProxy;
|
||
strTemp.Format(_T("%s-%d"),AfxGetAppName(),GetTickCount());
|
||
if ( setup.bProxyUse ) //使用代理
|
||
{
|
||
switch(setup.lProxyType)
|
||
{
|
||
case 0: //SOCKS 4
|
||
case 1: //SOCKS 4A
|
||
case 2: //SOCKS 5
|
||
strProxy.Format( _T("SOCKS=%s:%d") , setup.szProxyIP , setup.lProxyPort );
|
||
break;
|
||
case 3: //http
|
||
//strProxy.Format( _T("HTTP://%s:%d") , setup.szProxyIP , setup.lProxyPort );
|
||
strProxy.Format( _T("%s:%d") , setup.szProxyIP , setup.lProxyPort );
|
||
break;
|
||
}
|
||
m_hInternet = InternetOpen(strTemp,INTERNET_OPEN_TYPE_PROXY ,strProxy,NULL,0);
|
||
}
|
||
else
|
||
{
|
||
m_hInternet = InternetOpen(strTemp,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
|
||
}
|
||
if ( !m_hInternet )
|
||
return false;
|
||
|
||
//设置代理用户名及密码
|
||
if ( setup.bProxyUse ) //使用代理
|
||
{
|
||
INTERNET_PROXY_INFO proxyinfo;
|
||
proxyinfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
|
||
proxyinfo.lpszProxy = strProxy;
|
||
proxyinfo.lpszProxyBypass = NULL;
|
||
InternetSetOption(m_hInternet,INTERNET_OPTION_PROXY, (LPVOID)&proxyinfo, sizeof(INTERNET_PROXY_INFO));
|
||
|
||
if ( _tcslen(setup.szProxyUser)>0 )
|
||
{
|
||
InternetSetOption(m_hInternet,
|
||
INTERNET_OPTION_PROXY_USERNAME,
|
||
setup.szProxyUser,
|
||
_tcslen(setup.szProxyUser)+1);
|
||
}
|
||
if ( _tcslen(setup.szProxyPasswd)>0 )
|
||
{
|
||
InternetSetOption(m_hInternet,
|
||
INTERNET_OPTION_PROXY_PASSWORD,
|
||
setup.szProxyPasswd,
|
||
_tcslen(setup.szProxyPasswd)+1);
|
||
}
|
||
}
|
||
|
||
|
||
m_hConnection= InternetConnect(m_hInternet,m_Setup.szIP,INTERNET_DEFAULT_HTTP_PORT,_T(""),_T(""),INTERNET_SERVICE_HTTP,0,NULL);
|
||
if ( !m_hConnection )
|
||
return false;
|
||
|
||
m_bConnect = true;
|
||
m_bSend = true;
|
||
|
||
DWORD dwTemp;
|
||
m_hHttp=CreateThread(NULL,0,Http_Socket,(LPVOID)this,0,&dwTemp);
|
||
if ( m_hHttp==INVALID_HANDLE_VALUE )
|
||
{
|
||
Close();
|
||
return false;
|
||
}
|
||
SetThreadPriority(m_hHttp,THREAD_PRIORITY_LOWEST); //设置优先级
|
||
return true;
|
||
}
|
||
|
||
//设置代理信息
|
||
if ( !setup.bProxyUse )
|
||
{
|
||
this->SetProxy(PROXYTYPE_NOPROXY);
|
||
}
|
||
else
|
||
{
|
||
if ( setup.lProxyType == 0 || //Sock 4
|
||
setup.lProxyType == 1 ) //Sock 4a //这两种代理不用用户名与密码
|
||
{
|
||
#ifdef UNICODE
|
||
SetProxy(setup.lProxyType+1,CW2A(setup.szProxyIP),setup.lProxyPort);
|
||
#else
|
||
SetProxy(setup.lProxyType+1,setup.szProxyIP,setup.lProxyPort);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
if ( _tcslen(setup.szProxyUser) > 0 )
|
||
{
|
||
#ifdef UNICODE
|
||
SetProxy(setup.lProxyType+1,CW2A(setup.szProxyIP),setup.lProxyPort,CW2A(setup.szProxyUser),CW2A(setup.szProxyPasswd));
|
||
#else
|
||
SetProxy(setup.lProxyType+1,setup.szProxyIP,setup.lProxyPort,setup.szProxyUser,setup.szProxyPasswd);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef UNICODE
|
||
SetProxy(setup.lProxyType+1,CW2A(setup.szProxyIP),setup.lProxyPort);
|
||
#else
|
||
SetProxy(setup.lProxyType+1,setup.szProxyIP,setup.lProxyPort);
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
//创建
|
||
this->Create();
|
||
//连接
|
||
BOOL res;
|
||
srand(GetTickCount());
|
||
|
||
//分解IP及端口
|
||
#ifdef UNICODE
|
||
long lPort = DEFAULT_SERVERPORT_UNI;
|
||
#else
|
||
long lPort = DEFAULT_SERVERPORT;
|
||
#endif
|
||
CString strIP = setup.szIP;
|
||
CString strTemp = setup.szIP;
|
||
long lBegin = strIP.Find(_T(":"));
|
||
if ( lBegin>0 )
|
||
{
|
||
strIP = strTemp.Left(lBegin);
|
||
CString strPort = strTemp.Right(strTemp.GetLength()-lBegin-1);
|
||
if ( _ttol(strPort)>0 )
|
||
lPort = _ttol(strPort);
|
||
}
|
||
#ifdef _UNICODE
|
||
res=this->Connect(CW2A(strIP),lPort);
|
||
#else
|
||
res=this->Connect(strIP,lPort);
|
||
#endif
|
||
|
||
/*
|
||
if (!res)
|
||
{
|
||
if (GetLastError()!=WSAEWOULDBLOCK)
|
||
{
|
||
if (setup.bProxyUse)
|
||
AfxMessageBox("Error! Can't connect to proxy server!",MB_ICONEXCLAMATION);
|
||
else
|
||
AfxMessageBox("Error! Can't connect to server!",MB_ICONEXCLAMATION);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
*/
|
||
if ( GetLastError() == 1035 || GetLastError() !=0 )
|
||
{
|
||
m_bConnect = true;
|
||
return true;
|
||
}
|
||
/*
|
||
//连接第二个有效端口
|
||
res=this->Connect("211.154.104.141",80);
|
||
if ( GetLastError() == 1035 || GetLastError() !=0 )
|
||
{
|
||
m_bConnect = true;
|
||
return true;
|
||
}
|
||
*/
|
||
m_bConnect = false;
|
||
return false;
|
||
}
|
||
|
||
void CProcessSocket::Close()
|
||
{
|
||
if (m_hSocket != INVALID_SOCKET)
|
||
{
|
||
CAsyncProxySocket::Close();
|
||
}
|
||
//关闭超透网关的句柄
|
||
if ( m_hConnection != NULL )
|
||
{
|
||
InternetCloseHandle(m_hConnection);
|
||
}
|
||
if ( m_hInternet != NULL )
|
||
{
|
||
InternetCloseHandle(m_hInternet);
|
||
}
|
||
m_bConnect = false;
|
||
m_bSend = false;
|
||
|
||
if ( m_hHttp != INVALID_HANDLE_VALUE )
|
||
{
|
||
if (WaitForSingleObject(m_hHttp,3000)== WAIT_TIMEOUT )
|
||
TerminateThread(m_hHttp,0); //如果退出超时,强制结束线程
|
||
CloseHandle(m_hHttp);
|
||
m_hHttp = INVALID_HANDLE_VALUE;
|
||
}
|
||
|
||
|
||
//清除队列中的内容
|
||
while (!m_Frame.IsEmpty())
|
||
{
|
||
Socket_Head * pHead = m_Frame.GetHead();
|
||
m_Frame.RemoveHead();
|
||
delete pHead->pFrame;
|
||
delete pHead;
|
||
}
|
||
try
|
||
{
|
||
if ( m_pRecvFrame )
|
||
{
|
||
delete m_pRecvFrame;
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
|
||
}
|
||
|
||
m_lRecvHead = 0; //已收到的Head字节数
|
||
m_lRecvFrame= 0; //已收到的Frame字节数
|
||
m_bRecvFrame= false; //开始时不是在收Frame;
|
||
m_pRecvFrame= NULL;
|
||
}
|
||
|
||
BOOL CProcessSocket::SendFrame(unsigned char lFuncType, unsigned char *pFrame, unsigned long lFrameLen)
|
||
{
|
||
if ( !ConnectToServer(m_Setup) ) //连接到服务器,如果没连接,自动连接,如果连接上,则继续
|
||
{
|
||
delete pFrame;
|
||
return false;
|
||
}
|
||
Socket_Head * pHead = new Socket_Head;
|
||
memset( pHead , 0 , sizeof(Socket_Head) );
|
||
pHead->lFuncType = lFuncType; //功能号
|
||
pHead->bCompress = m_lCompress; //是否压缩
|
||
//pHead->lID = m_lID ++;
|
||
pHead->lID = MAKELPARAM(0xAFFF,CORPSMS_VER2);
|
||
pHead->lUserID = m_lUserID;
|
||
pHead->lUserType = LOGINTYPE_USER;
|
||
pHead->lFrameLen = lFrameLen;
|
||
pHead->pFrame = pFrame;
|
||
m_Frame.AddTail( pHead );
|
||
|
||
if ( !m_Setup.bGateWay && m_bSend ) //不使用超透网关时才使用Socket来发送数据
|
||
{
|
||
AsyncSelect(FD_WRITE|FD_READ|FD_CLOSE); //请求一个写事件,以发送数据
|
||
//AsyncSelect(FD_READ | FD_CLOSE);
|
||
}
|
||
return true;
|
||
}
|
||
BOOL CProcessSocket::SendFrameEx(DWORD lFuncType, unsigned char *pFrame, unsigned long lFrameLen)
|
||
{
|
||
if ( !ConnectToServer(m_Setup) ) //连接到服务器,如果没连接,自动连接,如果连接上,则继续
|
||
{
|
||
delete pFrame;
|
||
return false;
|
||
}
|
||
#ifdef _UNICODE
|
||
Socket_Head * pHead = new Socket_Head;
|
||
memset( pHead , 0 , sizeof(Socket_Head) );
|
||
pHead->lFuncType = lFuncType; //功能号
|
||
pHead->bCompress = m_lCompress; //是否压缩
|
||
//pHead->lID = m_lID ++;
|
||
pHead->lID = MAKELPARAM(0xAFFF,CORPSMS_VER2);
|
||
pHead->lUserID = m_lUserID;
|
||
pHead->lUserType = LOGINTYPE_USER;
|
||
pHead->lFrameLen = lFrameLen;
|
||
pHead->pFrame = pFrame;
|
||
m_Frame.AddTail( pHead );
|
||
#else
|
||
long lFrameLen2 = lFrameLen + sizeof(Socket_Head_Add);
|
||
BYTE * pData = new BYTE[lFrameLen2];
|
||
Socket_Head_Add * pAdd = (Socket_Head_Add *)pData; //增加头
|
||
BYTE * pFrame2 = pData + sizeof(Socket_Head_Add); //原数据
|
||
memset(pAdd , 0 , sizeof(Socket_Head_Add) );
|
||
pAdd->lFuncType = lFuncType;
|
||
pAdd->lFrameLen = lFrameLen;
|
||
memcpy(pFrame2 , pFrame , lFrameLen);
|
||
delete pFrame;
|
||
|
||
|
||
Socket_Head * pHead = new Socket_Head;
|
||
memset( pHead , 0 , sizeof(Socket_Head) );
|
||
pHead->lFuncType = SMSFUNC_EX; //功能号
|
||
pHead->bCompress = SENDDATA_COMPRESS; //是否压缩
|
||
//pHead->lID = m_lID ++;
|
||
pHead->lID = MAKELPARAM(0xAFFF,CORPSMS_VER2);
|
||
pHead->lUserID = m_lUserID;
|
||
pHead->lUserType = LOGINTYPE_USER;
|
||
pHead->lFrameLen = lFrameLen2;
|
||
pHead->pFrame = pData;
|
||
m_Frame.AddTail( pHead );
|
||
#endif
|
||
if ( !m_Setup.bGateWay && m_bSend ) //不使用超透网关时才使用Socket来发送数据
|
||
{
|
||
AsyncSelect(FD_WRITE|FD_READ|FD_CLOSE); //请求一个写事件,以发送数据
|
||
//AsyncSelect(FD_READ | FD_CLOSE);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void CProcessSocket::NotifyMainWnd(UINT nMsg, WPARAM wParam, LPARAM lParam)
|
||
{
|
||
if ( m_pWnd )
|
||
{
|
||
m_pWnd->PostMessage( nMsg , wParam , lParam );
|
||
//m_pWnd->SendMessage( nMsg , wParam , lParam );
|
||
}
|
||
}
|
||
void CProcessSocket::SetCompressType(int lCompressType)
|
||
{
|
||
m_lCompress = lCompressType;
|
||
if ( m_lCompress<0 || m_lCompress>2 )
|
||
m_lCompress=0;
|
||
}
|
||
void CProcessSocket::SetUserID(long lUserID)
|
||
{
|
||
m_lUserID = lUserID;
|
||
}
|
||
|
||
int CProcessSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
|
||
{
|
||
#define SOCKET_SEND_TIMEOUT 10000 //10秒发送超时
|
||
if ( nBufLen<=0 )
|
||
return 0;
|
||
long lSended = 0;
|
||
DWORD lTimeOut = ::GetTickCount();
|
||
while ( 1 )
|
||
{
|
||
long lRet = CAsyncSocket::Send(((UCHAR*)lpBuf+lSended), nBufLen-lSended, nFlags);
|
||
if ( lRet == SOCKET_ERROR ) //发送错误
|
||
{
|
||
if ( GetLastError() != WSAEWOULDBLOCK ) //绶区已满
|
||
return SOCKET_ERROR;
|
||
}
|
||
|
||
if ( lRet > 0 )
|
||
{
|
||
lSended += lRet;
|
||
if ( lSended >= nBufLen )
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
Sleep( 50 ); //绶冲区已满,稍等
|
||
}
|
||
if ( ::GetTickCount() - lTimeOut > SOCKET_SEND_TIMEOUT )
|
||
break;
|
||
}
|
||
return lSended;
|
||
}
|
||
|
||
DWORD WINAPI CProcessSocket::Http_Socket(LPVOID lParam)
|
||
{
|
||
#define REQHEAD "MOBSETGATEWAY002"
|
||
CProcessSocket * pPro = (CProcessSocket *)lParam;
|
||
try
|
||
{
|
||
while ( pPro->m_bConnect && pPro->m_bSend )
|
||
{
|
||
//发送队列中的内容
|
||
while (!pPro->m_Frame.IsEmpty())
|
||
{
|
||
Socket_Head * pHead = pPro->m_Frame.GetHead();
|
||
ULONG lSendFrameLen = pHead->lFrameLen; //最终需要发送的长度
|
||
BOOL bOK = true;
|
||
pPro->m_Frame.RemoveHead();
|
||
if ( pHead->bCompress>0 )
|
||
{
|
||
bOK = false;
|
||
ULONG lCount = pHead->lFrameLen + 2048;
|
||
BYTE * pFrame = new BYTE[lCount];memset(pFrame , 0 , lCount);
|
||
|
||
if ( pHead->bCompress==1 )
|
||
{
|
||
if ( pPro->lzo.Compress( pHead->pFrame , pHead->lFrameLen , pFrame , &lCount )>0 && lCount > 0 )
|
||
{
|
||
bOK = true;
|
||
}
|
||
}
|
||
if ( pHead->bCompress==2 )
|
||
{
|
||
if ( compress( pFrame , &lCount,pHead->pFrame , pHead->lFrameLen )==Z_OK && lCount > 0 )
|
||
{
|
||
bOK = true;
|
||
}
|
||
}
|
||
if ( bOK )
|
||
{
|
||
delete pHead->pFrame; //压缩成功,替换要发送的内容
|
||
pHead->pFrame = pFrame;
|
||
pHead->lCompressLen = lCount;
|
||
lSendFrameLen = lCount; //最终要发送的字节数
|
||
}
|
||
else
|
||
{
|
||
delete pFrame;
|
||
}
|
||
}
|
||
if ( bOK )
|
||
{
|
||
//计算需要发送的字节数
|
||
long lSendBytes = (sizeof(Socket_Head)+lSendFrameLen)*2;
|
||
//生成请求文件
|
||
char szBegin[256]={0};strcpy(szBegin,"SMS=");strcat(szBegin,REQHEAD);
|
||
char szBegin2[256]={0};sprintf(szBegin2,"%010d",lSendBytes);
|
||
strcat(szBegin,szBegin2); //头+长度+内容
|
||
char szEnd[256]={0};strcpy(szEnd,"&Submit=%CC%E1%BD%BB");
|
||
lSendBytes=lSendBytes+strlen(szBegin)+strlen(szEnd);
|
||
char * pSend = new char[lSendBytes+10];
|
||
memset(pSend ,0,lSendBytes+10);
|
||
|
||
//加入头
|
||
strcpy(pSend,szBegin);
|
||
char * pSend2 = pSend + strlen(szBegin);
|
||
//加入内容
|
||
AsciiToHex((char*)pHead ,pSend2,sizeof(Socket_Head));pSend2=pSend2+sizeof(Socket_Head)*2;
|
||
AsciiToHex((char*)pHead->pFrame,pSend2,lSendFrameLen);pSend2=pSend2+lSendFrameLen*2;
|
||
//加入尾
|
||
strcpy(pSend2,szEnd);
|
||
|
||
char szAcceptType[32]={0};
|
||
strcpy(szAcceptType,"*/*");
|
||
|
||
HINTERNET hHttpFile = HttpOpenRequest(pPro->m_hConnection,
|
||
_T("POST"),
|
||
SUPPERGATEWAY_POST,
|
||
HTTP_VERSION,
|
||
NULL,
|
||
NULL,
|
||
INTERNET_FLAG_RELOAD,
|
||
0);
|
||
|
||
//设置代理
|
||
|
||
//设置代理用户名及密码
|
||
if ( pPro->m_Setup.bProxyUse ) //使用代理
|
||
{
|
||
/*
|
||
CString strProxy;
|
||
INTERNET_PROXY_INFO proxyinfo;
|
||
proxyinfo.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
|
||
proxyinfo.lpszProxy = strProxy;
|
||
proxyinfo.lpszProxyBypass = NULL;
|
||
InternetSetOption(m_hInternet,INTERNET_OPTION_PROXY, (LPVOID)&proxyinfo, sizeof(INTERNET_PROXY_INFO));
|
||
*/
|
||
|
||
if ( _tcslen(pPro->m_Setup.szProxyUser)>0 )
|
||
{
|
||
InternetSetOption(hHttpFile,
|
||
INTERNET_OPTION_PROXY_USERNAME,
|
||
pPro->m_Setup.szProxyUser,
|
||
_tcslen(pPro->m_Setup.szProxyUser)+1);
|
||
}
|
||
if ( _tcslen(pPro->m_Setup.szProxyPasswd)>0 )
|
||
{
|
||
InternetSetOption(hHttpFile,
|
||
INTERNET_OPTION_PROXY_PASSWORD,
|
||
pPro->m_Setup.szProxyPasswd,
|
||
_tcslen(pPro->m_Setup.szProxyPasswd)+1);
|
||
}
|
||
}
|
||
//TRACE(pSend);
|
||
/*
|
||
#ifdef _DEBUG
|
||
CFile file(_T("d:\\gateway_send.txt") , CFile::modeCreate|CFile::modeReadWrite);
|
||
file.Write(pSend , lSendBytes);
|
||
file.Close();
|
||
#endif
|
||
*/
|
||
// Send the request.
|
||
CString Head=_T("Content-Type: application/x-www-form-urlencoded");
|
||
BOOL bSendRequest = ::HttpSendRequest(hHttpFile, Head,Head.GetLength(), pSend, lSendBytes);
|
||
|
||
/*
|
||
// Get the length of the file.
|
||
char bufQuery[32] ;
|
||
DWORD dwIndex=0;
|
||
DWORD dwLengthBufQuery = sizeof(bufQuery);
|
||
BOOL bQuery = HttpQueryInfo(hHttpFile,
|
||
HTTP_QUERY_CONTENT_LENGTH,
|
||
bufQuery,
|
||
&dwLengthBufQuery,
|
||
&dwIndex);
|
||
// Convert length from ASCII string to a DWORD.
|
||
DWORD dwFileSize = (DWORD)atol(bufQuery) ;
|
||
if ( dwFileSize >0 )
|
||
*/
|
||
//::HttpEndRequest(
|
||
DWORD lMaxBufSize=512*1024;
|
||
char* pRecv = new char[lMaxBufSize];
|
||
memset(pRecv , 0 , lMaxBufSize);
|
||
DWORD dwReadLen=0;
|
||
for (int i=0;i<1000;i++) //最多读取100次
|
||
{
|
||
DWORD dwBytesRead = 0;
|
||
BOOL bRead = ::InternetReadFile(hHttpFile,
|
||
pRecv+dwReadLen,
|
||
lMaxBufSize-dwReadLen,
|
||
&dwBytesRead);
|
||
|
||
dwReadLen += dwBytesRead;
|
||
|
||
if ( (bRead && dwBytesRead<=0) || dwReadLen>=lMaxBufSize )
|
||
break;
|
||
|
||
Sleep(30);
|
||
}
|
||
/*
|
||
#ifdef _DEBUG
|
||
if (i>=100 )
|
||
{
|
||
int abc=219323;
|
||
}
|
||
CFile file2(_T("d:\\gateway_recv.txt") , CFile::modeCreate|CFile::modeReadWrite);
|
||
file2.Write(pRecv , dwReadLen);
|
||
file2.Close();
|
||
#endif
|
||
*/
|
||
long dwBytesRead = dwReadLen;
|
||
//处理接收到的信息
|
||
if (!strncmp(pRecv,REQHEAD,strlen(REQHEAD)) ) //接收到的是正确的消息
|
||
{
|
||
//转换数据
|
||
dwBytesRead = dwBytesRead-strlen(REQHEAD);
|
||
BYTE * pData = new BYTE[dwBytesRead];
|
||
memset(pData,0,dwBytesRead);
|
||
HexToAscii((char*)(pRecv+strlen(REQHEAD)),(char*)pData);
|
||
long lDataLen = dwBytesRead/2;
|
||
|
||
for ( int i=0 ; i<lDataLen ; i++ )
|
||
{
|
||
Socket_Head SHead={0};
|
||
memcpy(&SHead,pData+i,sizeof(Socket_Head)); i=i+sizeof(Socket_Head);
|
||
long lGetLen=SHead.lFrameLen;
|
||
if ( SHead.bCompress>0 )
|
||
lGetLen = SHead.lCompressLen;
|
||
if ( i+lGetLen>lDataLen) //数据不够
|
||
{
|
||
break;
|
||
}
|
||
BYTE * pFrame = NULL;
|
||
BOOL bOK = true;
|
||
if ( SHead.lFuncType != SMSFUNC_TEST )
|
||
pPro->SetCompressType(SHead.bCompress); //取来自服务器的压缩选项
|
||
if ( SHead.bCompress>0 ) //解压
|
||
{
|
||
ULONG lCount = SHead.lFrameLen+2048;
|
||
pFrame = new BYTE[lCount];memset( pFrame , 0 , lCount );
|
||
|
||
if ( SHead.bCompress == 1 )
|
||
{
|
||
if ( !pPro->lzo.decompress( pData+i , lGetLen , pFrame , &lCount ))
|
||
{
|
||
bOK = false; //解压不成功,不用通知收到帧
|
||
//解压不成功
|
||
delete pFrame;
|
||
}
|
||
}
|
||
if ( SHead.bCompress == 2 )
|
||
{
|
||
if ( uncompress( pFrame , &lCount , pData+i , lGetLen )!=Z_OK)
|
||
{
|
||
bOK = false; //解压不成功,不用通知收到帧
|
||
//解压不成功
|
||
delete pFrame;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ULONG lCount = lGetLen+512;
|
||
pFrame = new BYTE[lCount];memset( pFrame , 0 , lCount );
|
||
memcpy(pFrame,pData+i,lGetLen);
|
||
}
|
||
if ( bOK )
|
||
{
|
||
Socket_Head * pHead = new Socket_Head;
|
||
*pHead = SHead;
|
||
pHead->pFrame = pFrame;
|
||
pPro->NotifyMainWnd( PROCESSSOCKET_FRAME , (WPARAM)pHead , 0 );
|
||
}
|
||
i=i+lGetLen;
|
||
i=i-1;
|
||
}
|
||
delete pData;
|
||
}
|
||
delete pRecv;
|
||
delete pSend;
|
||
InternetCloseHandle(hHttpFile);
|
||
}
|
||
delete pHead->pFrame;
|
||
delete pHead;
|
||
}
|
||
|
||
Sleep(100); //累了,休息一下。
|
||
}
|
||
}
|
||
catch(...)
|
||
{
|
||
//有异常,重新启动线程
|
||
DWORD dwTemp;
|
||
pPro->m_hHttp = CreateThread(NULL,0,Http_Socket,(LPVOID)pPro,0,&dwTemp);
|
||
if ( pPro->m_hHttp != INVALID_HANDLE_VALUE )
|
||
{
|
||
SetThreadPriority(pPro->m_hHttp,THREAD_PRIORITY_LOWEST); //设置优先级
|
||
}
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void CProcessSocket::AsciiToHex(char *pszOrgRandom, char *pszDesRandom, long lLen)
|
||
{
|
||
char *p = (char *)pszDesRandom;
|
||
//long lLen = lstrlen( (char*)pszOrgRandom);
|
||
for( long i = 0; i < lLen; ++i )
|
||
{
|
||
sprintf(p, "%02X", (BYTE)pszOrgRandom[i] );
|
||
p += 2;
|
||
}
|
||
*p=0;
|
||
}
|
||
|
||
void CProcessSocket::HexToAscii(char *pszOrgRandom, char *pszDesRandom)
|
||
{
|
||
char Buf[4];
|
||
char *pDes = (char *)pszDesRandom;
|
||
char *pOrg = (char *)pszOrgRandom;
|
||
long lLen = strlen( pOrg);
|
||
long lTemp;
|
||
for( int i = 0; i < lLen/2; ++i )
|
||
{
|
||
memcpy( Buf , pOrg+i*2 , 2 );
|
||
Buf[2] = 0;
|
||
lTemp = CharHex(Buf[0])*16 + CharHex(Buf[1]);
|
||
pDes[i] = (char)lTemp;
|
||
}
|
||
pDes[i] = 0;
|
||
}
|
||
|
||
int CProcessSocket::CharHex(TCHAR ch)
|
||
{
|
||
//if( isdigit( ch ) ) return( atoi( &ch) );
|
||
if( ch >='0' && ch <= '9' ) return( _ttoi( &ch) );
|
||
else {
|
||
if( ch == 'a' || ch == 'A' ) return( 10 );
|
||
if( ch == 'b' || ch == 'B' ) return( 11 );
|
||
if( ch == 'c' || ch == 'C' ) return( 12 );
|
||
if( ch == 'd' || ch == 'D' ) return( 13 );
|
||
if( ch == 'e' || ch == 'E' ) return( 14 );
|
||
if( ch == 'f' || ch == 'F' ) return( 15 );
|
||
}
|
||
return( 0 );
|
||
}
|