www.gusucode.com > FreeEIM_VC++企业即时通讯软件源代码源码程序 > FreeEIM_VC++企业即时通讯软件源代码源码程序\code\xeim_message.cpp
//Download by http://www.NewXing.com #include "StdAfx.h" #include "../protocol/xeim_protocol.h" #include "xeim_logic.h" #include "xeim_message.h" #include "iocpui01Dlg.h" XEIM_MESSAGE::XEIM_MESSAGE(const SOCKET sock, const char *buf, const DWORD len, const LPVOID handle) { m_pMainTop = (CIocpui01Dlg*)AfxGetMainWnd(); m_sock = sock; memcpy((char*)&message, buf, sizeof(DWORD)); memcpy(buffer, buf+sizeof(DWORD), len-sizeof(DWORD)); length = len - sizeof(DWORD); m_pHandle = handle; ProcessMessage(); } XEIM_MESSAGE::XEIM_MESSAGE(XEIM_OPERATION *PerIoData, XEIM_HANDLE *PerHandleData) { m_pMainTop = (CIocpui01Dlg*)AfxGetMainWnd(); m_sock = PerHandleData->Socket; memcpy((char*)&message, PerIoData->buf, sizeof(DWORD)); length = PerIoData->Offset - sizeof(DWORD); memcpy(buffer, PerIoData->buf+sizeof(DWORD), length); m_pHandle = PerIoData; ProcessMessage(); } XEIM_MESSAGE::~XEIM_MESSAGE() { } void XEIM_MESSAGE::ProcessMessage() { /* CString str; str.Format("%d", length); AfxMessageBox(str);*/ switch (message) { case XEIM_NONE: OnXEIM_None(buffer, length); break; case XEIM_ECHO: OnXEIM_Echo(buffer, length); break; case XEIM_LOGIN: OnXEIM_Login(buffer, length); break; case XEIM_FOLDER: OnXEIM_Folder(buffer, length); break; case XEIM_FILE: OnXEIM_File(buffer, length); break; case XEIM_FILE_DATA: OnXEIM_File_Data(buffer, length); break; case XEIM_FILE_DATA_LAST: OnXEIM_File_Last(); break; default: OnXEIM_Unknown(); } } void XEIM_MESSAGE::OnXEIM_None(char *buf, DWORD len) { } void XEIM_MESSAGE::OnXEIM_Echo(char *buf, DWORD len) { } // 用户登录消息处理 void XEIM_MESSAGE::OnXEIM_Login(char *buf, DWORD len) { if (! IsNewSocket()) { } else { char szUser[128]; char szPassword[128]; char szVersion[16]; char szStatus[8]; int nLen; GetDataByTag(buf, len, ',', 1, szUser, nLen, 128); GetDataByTag(buf, len, ',', 2, szPassword, nLen, 128); GetDataByTag(buf, len, ',', 3, szVersion, nLen, 16); GetDataByTag(buf, len, ',', 4, szStatus, nLen, 8); XEIM_LOGIC xlogic; if (xlogic.UserValid(szUser, szPassword)) { LVITEM lvi; int nIdx; lvi.mask = LVIF_IMAGE | LVIF_TEXT; lvi.iItem = 0xff; lvi.iSubItem = 0; lvi.pszText = szUser; lvi.iImage = I_IMAGECALLBACK; // There are 8 images in the image list nIdx = m_pMainTop->m_reportClient.InsertItem(& lvi); m_pMainTop->m_reportClient.SetItemData(nIdx, m_sock); sockaddr_in aa; int slen = sizeof(aa); int rval = 0; if (getpeername(m_sock, (sockaddr*)&aa, &slen) == SOCKET_ERROR) { m_pMainTop->m_reportClient.SetItemText(nIdx, 1, "0.0.0.0"); } else { m_pMainTop->m_reportClient.SetItemText(nIdx, 1, inet_ntoa(aa.sin_addr)); } ////////////////////////////////////////////////////////////////////////// SetBuffer(XEIM_LOGIN, "OK", 3); } else { SetBuffer(XEIM_LOGIN, "NO", 3); } } } // 文件夹消息 void XEIM_MESSAGE::OnXEIM_Folder(char *buf, DWORD len) { } // 文件消息 /* CString stra; stra.Format("创建时间:%s\r\n" "修改时间:%s\r\n" "访问时间:%s\r\n" "大小:%f\r\n" "文件名称:%s\r\n", status.m_ctime.Format("%Y-%m-%d %H:%M:%S"), status.m_mtime.Format("%Y-%m-%d %H:%M-%S"), status.m_atime.Format("%Y-%m-%d %H:%M-%S"), (float)status.m_size, status.m_szFullName); AfxMessageBox(stra); */ void XEIM_MESSAGE::OnXEIM_File(char *buf, DWORD len) { CFileStatus status = * (CFileStatus*)buf; char fileName[MAX_PATH]; XEIM_LOGIC xLogic; xLogic.SetSaveFileName(status.m_szFullName, "aaaa", fileName); CString strXtFileName = fileName; strXtFileName += ".xeim"; CFile *pFile = new CFile; ((XEIM_OPERATION*)m_pHandle)->handle = pFile; if (IsFileResume(status, fileName)) { BOOL bOK = pFile->Open(strXtFileName, CFile::modeNoTruncate|CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive, NULL); if (bOK) { DWORD fSize = pFile->GetLength(); SetBuffer(XEIM_FILE_RESUME, (char*)&fSize, sizeof(DWORD)); pFile->Seek(0, CFile::end); } else // Some error. { // SetBuffer(XEIM_FILE_RESUME, 0, sizeof(DWORD)); SetBuffer(XEIM_FILE, "NO", 3); } } else { // 保存文件信息 SaveFileStatus(status, fileName); // 文件信息不同的话,即使存在旧文件,也要清 0 再重新写,用 CFile::modeCreate。 BOOL bOK = pFile->Open(strXtFileName, CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive, NULL); if (bOK) { SetBuffer(XEIM_FILE, "OK", 3); } else { SetBuffer(XEIM_FILE, "NO", 3); } } } // 文件数据消息 void XEIM_MESSAGE::OnXEIM_File_Data(char *buf, DWORD len) { // AfxMessageBox("OnXEIM_File_Data"); CFile *pFile = (CFile*)(((XEIM_OPERATION*)m_pHandle)->handle); pFile->Write(buf, len); SetBuffer(XEIM_FILE_DATA, "OK", 3); } // 文件最后一个数据包 void XEIM_MESSAGE::OnXEIM_File_Last() { CString strFileName; CString strOldFileName; CFile *pFile = (CFile*)(((XEIM_OPERATION*)m_pHandle)->handle); pFile->Write(buffer, length); SetBuffer(XEIM_FILE_DATA_LAST, "OK", 3); // AfxMessageBox("OnXEIM_File_Last"); strOldFileName = pFile->GetFilePath(); strFileName = strOldFileName; strFileName.Replace(".xeim", ""); pFile->Flush(); pFile->Close(); XEIM_Rename(strOldFileName, strFileName); // CFile::Rename(strOldFileName, strFileName); // AfxMessageBox(strFileName + ".info"); CFile::Remove(strFileName + ".info"); XEIM_DELETE_CFILE(((XEIM_OPERATION*)m_pHandle)->handle); /* delete pFile; ((XEIM_OPERATION*)m_pHandle)->handle = NULL;*/ } // 未知的消息 void XEIM_MESSAGE::OnXEIM_Unknown() { SetBuffer(message, "UNKNOWN", strlen("UNKNOWN")); } BOOL XEIM_MESSAGE::IsNewSocket() { int nItemCount = m_pMainTop->m_reportClient.GetItemCount(); for (int i=0; i<nItemCount; i++) { SOCKET sock = m_pMainTop->m_reportClient.GetItemData(i); if (sock == m_sock) { return FALSE; } } return TRUE; } // 设置返回的缓存区。 void XEIM_MESSAGE::SetBuffer(DWORD msg, char *buf, DWORD len) { length = len+4; memcpy(buffer, (char*)&msg, sizeof(DWORD)); memcpy(buffer+sizeof(DWORD), buf, len); } ////////////////////////////////////////////////////////////////////////// // 一些协助函数都放到最后 // XEIM 数据流处理函数,通过分隔符 Separator 来获取每个段的数据。 // 编写日期:21:44 2009-8-18 // FEIM 小组:飞鸽传书 www.freeeim.com // 使用说明: /* pSrcData 为输入数据流; nSrcLen 为数据流的长度; cSeparator 为分隔符; nIndex 为第几个分隔符内的数据; pDstData 分隔符数据保存到此缓冲区; nDstLen 该分隔符内数据长度; nMaxSize 输出缓存区大小,假如该分割符内的数据是4字节,你给3字节函数就失败,*pDstLen = NULL。 */ /* 使用例子: char * src = "aa,bbbbbbbb,cc,dd"; int len = strlen(src) + 1; char * dst = new char[1024]; memset(dst, 0, 1024); int dstLen; GetDataByTag(src, len, ',', 4, dst, dstLen, 1024); printf("%s -- %d", dst, dstLen); */ // 输出结果:dd -- 2 void XEIM_MESSAGE::GetDataByTag(IN char *pSrcData, IN int nSrcLen, IN char cSeparator, IN int nIndex, OUT char *pDstData, OUT int &nDstLen, int nMaxSize) { int i_1st = -1; int i_2nd = 0; int idx =0; for (; i_2nd<nSrcLen&&idx<nIndex;i_2nd++) { if (*(pSrcData+i_2nd) == cSeparator) { if (nIndex-2 == idx) i_1st = i_2nd; idx ++; } } if (i_1st == -1 && i_2nd == nSrcLen || (i_2nd-i_1st-2) >= nMaxSize) { *pDstData = NULL; nDstLen = 0; return; } i_1st ++; i_2nd --; for (idx=0; i_1st+idx<i_2nd; idx++) *(pDstData+idx) = *(pSrcData+i_1st+idx); *(pDstData+idx) = NULL; nDstLen = idx; } // 写时冲冲,未留注释,获取文件名称 /* CFile file; BOOL bResult = file.Open("c:\\windows\\notepad.exe", CFile::modeRead|CFile::shareDenyNone, NULL); CFileStatus status; file.GetStatus(status); printf("创建时间:%s\r\n", status.m_ctime.Format("%Y-%m-%d %H:%M:%S")); printf("修改时间:%s\r\n", status.m_mtime.Format("%Y-%m-%d %H:%M-%S")); printf("访问时间:%s\r\n", status.m_atime.Format("%Y-%m-%d %H:%M-%S")); printf("大小:%f\r\n", (float)status.m_size); printf("文件名称:%s\r\n", status.m_szFullName); printf("CFileStatus:%d\r\n", sizeof(CFileStatus)); char fileName[MAX_PATH]; GetFileName(status.m_szFullName, fileName); printf("%s\r\n", fileName); GetFileExt(status.m_szFullName, fileName); printf("%s\r\n", fileName); */ void XEIM_MESSAGE::GetFileName(IN char* fullPathName, OUT char *fileName) { int idx=0; int kk; while(fullPathName[idx] != NULL) { if (fullPathName[idx] == '\\') kk = idx; idx ++; } kk ++; for (int i=0;fullPathName[kk+i];i++) { fileName[i] = fullPathName[kk+i]; } fileName[i] = NULL; // printf("%d - %s\r\n", kk, fileName); } // 写时冲冲,未留注释,获取文件扩展名 /* CFile file; BOOL bResult = file.Open("c:\\windows\\notepad.exe", CFile::modeRead|CFile::shareDenyNone, NULL); CFileStatus status; file.GetStatus(status); printf("创建时间:%s\r\n", status.m_ctime.Format("%Y-%m-%d %H:%M:%S")); printf("修改时间:%s\r\n", status.m_mtime.Format("%Y-%m-%d %H:%M-%S")); printf("访问时间:%s\r\n", status.m_atime.Format("%Y-%m-%d %H:%M-%S")); printf("大小:%f\r\n", (float)status.m_size); printf("文件名称:%s\r\n", status.m_szFullName); printf("CFileStatus:%d\r\n", sizeof(CFileStatus)); char fileName[MAX_PATH]; GetFileName(status.m_szFullName, fileName); printf("%s\r\n", fileName); GetFileExt(status.m_szFullName, fileName); printf("%s\r\n", fileName); */ void XEIM_MESSAGE::GetFileExt(IN char* fileName, OUT char *fileExt) { int idx = 0; int kk; while(fileName[idx] != NULL) { if (fileName[idx] == '.') kk = idx; idx ++; } kk ++; for (int i=0;fileName[kk+i];i++) { fileExt[i] = fileName[kk+i]; } fileExt[i] = NULL; // printf("%d - %s\r\n", kk, fileExt); } // 保存文件信息,用于续传 void XEIM_MESSAGE::SaveFileStatus(CFileStatus &status, char *fileName) { CString strFileName = fileName; strFileName += ".info"; TRY{ CFile file; CFileException except; BOOL bResult = file.Open(strFileName, CFile::modeWrite|CFile::modeCreate|CFile::shareDenyNone, &except); if (bResult) { file.Write((char*)&status, sizeof(CFileStatus)); file.Flush(); file.Close(); } int err = except.m_cause; } CATCH(CFileException ,e){ if (e->m_cause == CFileException::fileNotFound) AfxMessageBox("Not found."); } END_CATCH } // 判断该文件信息是否已存在,有则进行续传 BOOL XEIM_MESSAGE::IsFileResume(CFileStatus &status, char *fileName) { CString strFileName = fileName; strFileName += ".info"; CFile file; BOOL bResult = file.Open(strFileName, CFile::modeRead|CFile::shareDenyNone, NULL); if (! bResult) return FALSE; CFileStatus l_status; file.Read((char*)&l_status, sizeof(CFileStatus)); file.Close(); // 访问时间当然每次都变啦。 l_status.m_atime = status.m_atime; return (0 == memcmp((char*)&l_status, (char*)&status, sizeof(CFileStatus))); } // 重命名一个文件,如果新名字存在一个文件,就把它删了; void XEIM_MESSAGE::XEIM_Rename(LPCTSTR pstrExisting, LPCTSTR pstrNew) { OFSTRUCT ofStruct; ofStruct.cBytes = sizeof(OFSTRUCT); ofStruct.fFixedDisk = 1; if (HFILE_ERROR != ::OpenFile(pstrNew, &ofStruct, OF_EXIST)) CFile::Remove(pstrNew); CFile::Rename(pstrExisting, pstrNew); }