模拟MSN源码
模拟msn源代码-(与sb服务器通信,聊天session)- -
// MsnUser.cpp : implementation file
//
#include "stdafx.h"
#include "SimMsnMessenger.h"
#include "MsnUser.h"
#include "MsnLoginClient.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern char agCurDir[];
/////////////////////////////////////////////////////////////////////////////
// CMsnUser
CMsnUser::CMsnUser()
{
m_iSendXh=0;
m_iFree=1;
m_iCountMsg=0;
}
CMsnUser::~CMsnUser()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMsnUser, CAsyncSocket)
//{{AFX_MSG_MAP(CMsnUser)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CMsnUser member functions
int CMsnUser::SBInit(char *aInServer, char *aInCKI)
{
if( m_iFree == 0 )
{
FileLog( "SBInit m_iFree=[%d], return -1", m_iFree);
return -1;
}
m_iFree=0;
unsigned int ilLen=strlen(aInServer);
unsigned int i;
for( i=2; i < ilLen ; i++ )
{
if( aInServer[i]== ':' ) break;
}
aInServer[i]=0x00;
m_strCKI.Format("%s",aInCKI);
m_Server.Format("%s",aInServer);
m_iPort = atoi( aInServer+i+1 );
FileLog( "[UserNo: %d] SBInit Connect(%s:%d) m_iFree=[%d]...",m_iUserNo ,(LPCTSTR)m_Server,m_iPort,m_iFree);
Create(0,SOCK_STREAM,FD_CONNECT);
Connect((LPCTSTR)m_Server,m_iPort);
return 0;
}
void CMsnUser::OnConnect(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
FileLog("SB: [UserNo: %d] OnConnect(%d)",m_iUserNo , nErrorCode);
AsyncSelect( FD_READ|FD_CLOSE ); //提请一个“读”的网络事件,准备接收
char buf[1000];
memset(buf,0x00,1000);
m_iSendXh++;
if( !m_strSessionID.CompareNoCase("XFR") )
{
//主动请求
//USR 1 tcpip_2005@126.com 17151585.1116982922.3576
sprintf( buf,"USR %d %s %s/r/n",
m_iSendXh,(LPCTSTR)m_pLoginClient->m_strMyNickName,
(LPCTSTR)m_strCKI);
}
else
{
//被动接受请求
//ANS 1 tcpip_2005@126.com 989495494.750408580 11742066
//上面的命令包含了我们的登陆名,我们接收到的CKI杂列和session号.
sprintf( buf,"ANS %d %s %s %s/r/n",
m_iSendXh,(LPCTSTR)m_pLoginClient->m_strMyNickName,
(LPCTSTR)m_strCKI,(LPCTSTR)m_strSessionID);
}
int iTem = strlen(buf);
buf[iTem] = 0x00;
iTem = Send( (void*)buf, strlen(buf));
FileLog("Send ret =[%d]", iTem );
CAsyncSocket::OnConnect(nErrorCode);
}
void CMsnUser::OnReceive(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
char bufRecv[2048];
int iTem;
int iLen;
int iStart, iEnd;
char cTem;
CString strTem1,strTem2;
int i;
iLen = this->Receive( bufRecv, 2047 );
if( iLen <=0 )
{
FileLog("<-Reveive %04d bytes:<span style=/"background-color: #0000FF/">[ERROR!!]</span>", iLen);
return;
}
if (iLen >= 2047 ) iLen = 2047;
bufRecv[iLen] = 0x00;
if( iLen < 80 ) FileLog("<-SB : [UserNo: %d] Reveive %04d bytes::<span style=/"background-color: #669999/">[%s]</span>", m_iUserNo , iLen , bufRecv);
else FileLog("<-SB : [UserNo: %d] Reveive %04d bytes::<span style=/"background-color: #669999/">[<br>%s]</span>", m_iUserNo , iLen , bufRecv);
if(m_pLoginClient != NULL)
{
//process the recved Message:
iStart = iEnd = 0;
cTem = bufRecv[0];
strTem1 = CString(bufRecv);
i = 0;
iTem = strTem1.GetLength();
for(;iEnd < iTem;)
{
iEnd = strTem1.Find(_T("/r/n")); //?? CR LF?
if(iEnd == -1)
{
FileLog("Not Find CR LF ! Error!");
iEnd = strTem1.GetLength();
}
strTem2 = strTem1.Mid(0,iEnd);
m_iBytesForCmd=0;
DoRecvedStr(strTem2);
if( m_iBytesForCmd > 0 )
{
strTem2 = strTem1.Mid(iEnd+2,iEnd+2+m_iBytesForCmd);
DoMSG(strTem2, m_iBytesForCmd);
iEnd=iEnd+m_iBytesForCmd;
}
iTem = strTem1.GetLength();
if(iEnd+2 >= iTem) break;
strTem1 = strTem1.Mid(iEnd+2,iTem);
i++;
}
}
CAsyncSocket::OnReceive(nErrorCode);
}
int CMsnUser::Send(const void* lpBuf, int nBufLen, int nFlags)
{
// TODO: Add your specialized code here and/or call the base class
FileLog("->SB : [UserNo: %d] Send %04d bytes::<span style=/"background-color: #CC6600/">[%s]</span>", m_iUserNo , nBufLen , lpBuf);
return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}
int CMsnUser::DoRecvedStr(CString strMsg)
{
FileLog("[UserNo: %d] DoRecvedStr(%s)", m_iUserNo , (LPCTSTR) strMsg);
CString strCommand;
char buf[500];
int iTem;
char alTmp0[1000],alTmp1[100],alTmp2[100],alTmp3[100],alTmp4[1000];
unsigned int i=0;
//MSN Messenger命令使用纯ASCII码。对非ASCII码字符使用URL编码。
//命令的语法是
//XXX[<SP>TrID<SP>PARAM1<SP>PARAM2…]<CRLF>
//其中,<SP>是空白字符,<CRLF>是回车换行,
//XXX是一个3字符的命令串,TrID是一个流水号,PARAMx是参数,
//[ ]内是可选项。最简单的命令没有流水号和参数。
//为了方便起见,下面讨论时用" "代表<SP>,"/r/n"代表<CRLF>,
//"/x??"代表一个值为0x??字节。
//USR 18 TWN I tcpip_2005@126.com/r/n
strCommand = strMsg.Mid(0,3);
if(strCommand == CString("IRO"))
{
FileLog("[UserNo: %d] IRO 通话Session已经建立", m_iUserNo);
}
else if(strCommand == CString("ANS"))
{
FileLog("[UserNo: %d] ANS 确认通话Session已经建立!", m_iUserNo);
WriteMsgFile( "Talk session init OK!", 99 );
}
else if(strCommand == CString("USR"))
{
//USR 1 OK tcpip_2005@126.com
FileLog("[UserNo: %d] USR 确认通话Session已经建立!", m_iUserNo);
WriteMsgFile( "Talk session init OK!", 99 );
memset(alTmp0,0x00,sizeof(alTmp0));
memset(alTmp1,0x00,sizeof(alTmp1));
memset(alTmp2,0x00,sizeof(alTmp2));
memset(alTmp3,0x00,sizeof(alTmp3));
memset(alTmp4,0x00,sizeof(alTmp4));
sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
FileLog("XFR: %s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
// CAL 2 tcpip_2005@126.com
memset(buf,0x00,sizeof(buf));
m_iSendXh++;
sprintf(buf,"CAL %d %s/r/n",m_iSendXh,(LPCTSTR)m_strEmail);
iTem = strlen(buf);
buf[iTem] = 0x00;
Send( (void*)buf, strlen(buf));
}
else if(strCommand == CString("BYE"))
{
FileLog("[UserNo: %d] BYE SB断开通话Session!", m_iUserNo);
Close();
m_hSocket = INVALID_SOCKET;
m_iFree = 1 ;
WriteMsgFile( "Bye , Talk session was closed!", 99 );
}
else if(strCommand == CString("XFR"))
{
//XFR 3 NS 207.46.107.104:1863 0 207.46.104.20:1863%0d%0a
memset(alTmp0,0x00,sizeof(alTmp0));
memset(alTmp1,0x00,sizeof(alTmp1));
memset(alTmp2,0x00,sizeof(alTmp2));
memset(alTmp3,0x00,sizeof(alTmp3));
memset(alTmp4,0x00,sizeof(alTmp4));
sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
FileLog("XFR: %s %s %s %s",alTmp1,alTmp2,alTmp3,alTmp4);
memset(buf,0x00,sizeof(buf));
m_iSendXh++;
iTem = strlen(buf);
buf[iTem] = 0x0d; buf[iTem+1] = 0x0a; buf[iTem+2] = 0x00;
Send( (void*)buf, strlen(buf));
}
else if(strCommand == CString("MSG"))
{
//MSG Hotmail Hotmail 499
memset(alTmp0,0x00,sizeof(alTmp0));
memset(alTmp1,0x00,sizeof(alTmp1));
memset(alTmp2,0x00,sizeof(alTmp2));
memset(alTmp3,0x00,sizeof(alTmp3));
memset(alTmp4,0x00,sizeof(alTmp4));
sprintf(alTmp0,"%s",(LPCTSTR)strMsg);
int iLen;
sscanf(alTmp0,"%s %s %s %s",alTmp1,alTmp2,alTmp3 ,alTmp4);
iLen = atoi( alTmp4 );
FileLog("MSG : %s %s %s ,Len=%d",alTmp1,alTmp2,alTmp3 ,iLen);
m_iBytesForCmd = iLen;
}
else if(strCommand == CString("JOI"))
{
//[CAL 2 RINGING 17151585%0d%0a]
//[JOI tcpip_2005@126.com %e5%b0%8fI%e6%82%a0%e6%82%a0%0d%0a]
FileLog("[UserNo: %d] 通话Session OK!", m_iUserNo);
WriteMsgFile( "CAL OK!", 99 );
if( m_strWaitSend.GetLength() > 0 )
{
UserInputMsg( (LPCTSTR)m_strWaitSend );
}
}
return 0;
}
int CMsnUser::DoMSG(CString strMsg, int iInMsgLen)
{
FileLog("[UserNo: %d] DoMSG [%d]", m_iUserNo ,iInMsgLen);
WriteMsgFile( (LPCTSTR)strMsg , 0 );
/*************
memset(buf,0x00,sizeof(buf));
m_iSendXh++;
sprintf(buf,"MSG %d A %d/r/n",m_iSendXh,iInMsgLen);
iTem = strlen(buf);
buf[iTem] = 0x00;
Send( (void*)buf, strlen(buf));
Send( (LPCTSTR)strMsg,iInMsgLen);
***************/
return 0;
}
void CMsnUser::OnClose(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
FileLog("[UserNo: %d] OnClose(%d ) SB断开通话Sessio!", m_iUserNo,nErrorCode);
m_iFree = 1;
Close();
m_hSocket = INVALID_SOCKET;
WriteMsgFile( "Talk session was closed! Can't send message!", 99 );
CAsyncSocket::OnClose(nErrorCode);
}
int CMsnUser::WriteMsgFile(const char *aInMsg, int iIO)
{
char alTmp1[2048];
int ilBytes=strlen(aInMsg);
FILE *fp;
char fname1[300];
int ilIO=iIO;
memset(alTmp1,0x00,sizeof(alTmp1));
if( iIO == 0)
{
if( strstr(aInMsg,"Typing") != NULL )
{
memcpy( alTmp1,"Typing...", 9);
ilIO=99;
}
else
{
for( int i=0;i<ilBytes; i ++ )
{
if( strncmp(aInMsg+i , "/r/n/r/n",4 ) == 0 )
memcpy( alTmp1,aInMsg+i +4, ilBytes-i-4);
}
}
}
else memcpy( alTmp1,aInMsg , ilBytes );
sprintf(fname1,"%s//html//%d_user_left.htm",agCurDir,m_iUserNo);
FileLog("[UserNo: %d] %d %s", m_iUserNo,ilIO, fname1);
if (( fp = fopen(fname1,"a+")) == NULL) return(-1);
if( ilIO == 1) fprintf( fp,"%s say:<br>/n",(LPCTSTR)m_pLoginClient->m_strNick);
else if( ilIO == 0) fprintf( fp,"%s say:<br>/n",(LPCTSTR)m_strNickName);
else fprintf( fp,"Info : ");
fprintf( fp," %s<br>/n",alTmp1);
fclose( fp );
m_iCountMsg++;
FileLog("PostMessage(WPARAM, LPARAM lParam DispMainPage)");
LPARAM lpTmp= m_iUserNo+100;
AfxGetApp()->m_pMainWnd->PostMessage( WM_MY_MESSAGE, 1, (LPARAM)lpTmp );
return 0;
}
int CMsnUser::UserInputMsg(const char *aInMsg)
{
int iInMsgLen=strlen(aInMsg);
FileLog("[UserNo: %d] UserInputMsg Len=[%d]", m_iUserNo ,iInMsgLen);
char buf[500],buf1[1000];
int iTem,ilLen;
if( m_iFree == 1 )
{
FileLog("[UserNo: %d] session was closed!", m_iUserNo );
memset(buf1,0x00,sizeof(buf1));
sprintf(buf1,"Talk session was closed! Can't send message!");
WriteMsgFile( buf1, 99 );
m_strWaitSend+=aInMsg;
m_pLoginClient->DoUserXfrSB(m_iUserNo);
return -1;
}
memset(buf1,0x00,sizeof(buf1));
//sprintf(buf1,"MIME-Version: 1.0/r/nContent-Type: text/plain; charset=UTF-8/r/nX-MMS-IM-Format: FN=%%E5%%AE%%8B%%E4%%BD%%93; EF=; CO=0; CS=86; PF=0/r/n/r/n");
sprintf(buf1,"MIME-Version: 1.0/r/nContent-Type: text/plain; charset=UTF-8/r/nUser-Agent: Gaim/1.0.3/r/nX-MMS-IM-Format: FN=MS%%2520Sans%%2520Serif; EF=; CO=0; PF=0/r/n/r/n");
WriteMsgFile( aInMsg , 1 );
memset(buf,0x00,sizeof(buf));
m_iSendXh++;
sprintf(buf,"MSG %d A %d/r/n",m_iSendXh,iInMsgLen+strlen(buf1));
iTem = strlen(buf);
buf[iTem] = 0x00;
ilLen = Send( (void*)buf, strlen(buf));
FileLog("[UserNo: %d] Send [%d] ret [%d]", m_iUserNo ,strlen(buf),ilLen);
ilLen = Send( (void*)buf1, strlen(buf1));
FileLog("[UserNo: %d] Send [%d] ret [%d]", m_iUserNo ,strlen(buf1),ilLen);
ilLen = Send( aInMsg,iInMsgLen);
FileLog("[UserNo: %d] Send [%d] ret [%d]", m_iUserNo ,iInMsgLen,ilLen);
return 0;
}