-

- 加为好友
- 发送私信
- 在线聊天
|
| 发表于:2008-08-22 14:54:40 楼主 |
DWORD WINAPI CFileServer::SendFile(LPVOID lp) { SEND_THREAD *m_lp = (SEND_THREAD*)lp; //每次包的长度 char chLen[10]; //返回检查包 char chCheck[3]; //返回值 int intRet; CCFileManager *m_FileMgr = CCFileManager::GetFileManager(); EnterCriticalSection(&(m_FileMgr->m_gs)); //获得内存临时文件, FILE_TABLE *m_File = m_FileMgr->GetFileList(m_lp->chFromUserName,m_lp->chToUserName); LeaveCriticalSection(&(m_FileMgr->m_gs)); //对方已取消发送 if(m_File->intIs == 4) { closesocket(m_lp->m_sock); m_FileMgr->DeleteFileNode(m_File); delete m_lp; return FALSE; } //计算包的个数 int intPackCount = m_File->intPackCount; //包个数 itoa(intPackCount,chLen,10); //发送包数量 send(m_lp->m_sock,chLen,10,0); //接收返回包 lop1:intRet = recv(m_lp->m_sock,chCheck,3,0); if(intRet == -1) { Sleep(1000); goto lop1; } //对方已关闭接收 if(intRet == 0) { //通知接收线程对方已不需要接收文件 m_File->intIs = 3; closesocket(m_lp->m_sock); delete m_lp; return FALSE; } for(int i=0;i <intPackCount;i++) { //若发送方已取消发送 if(m_File->intIs == 4) { closesocket(m_lp->m_sock); //删除结点 m_FileMgr->DeleteFileNode(m_File); delete m_lp; return FALSE; } //包长度 itoa(m_File->intBUFSize,chLen,10); //发送包长 send(m_lp->m_sock,chLen,10,0); //接收返回包 lop3: intRet = recv(m_lp->m_sock,chCheck,3,0); if(intRet == -1) { Sleep(1000); goto lop3; } //发送数据包 send(m_lp->m_sock, m_File->chBUF,m_File->intBUFSize,0); //接收返回包 lop4: intRet = recv(m_lp->m_sock,chCheck,3,0); if(intRet == -1) { Sleep(1000); goto lop4; } //若接收客户端已关闭 if(intRet == 0) { //对方已取消接收 m_File->intIs = 3; closesocket(m_lp->m_sock); delete m_lp; return FALSE; } EnterCriticalSection(&(m_File->gs_sec)); //已发送 m_File->intIs = 2; //可以删除内存 delete m_File->chBUF; m_File->chBUF = NULL; //数据工作区大小清0 m_File->intBUFSize = 0; //包个数自减1 m_File->intPackCount--; LeaveCriticalSection(&(m_File->gs_sec)); if(m_File->intPackCount !=0) { //挂起本地线程 SuspendThread(m_File->m_SendHandle); } } AfxMessageBox("Exit Send Thread"); closesocket(m_lp->m_sock); delete m_lp; return 0; } //接收文件 DWORD WINAPI CFileServer::ReceiveFile(LPVOID lp) { SEND_THREAD *m_lp = (SEND_THREAD*)lp; //返回值 int intRet; //包长 char chLen[10]; //返回检测包 char chCheck[3]; //包大小 int intPackLen; //已接收的包大小 int intHavRecv; FILE_PACK_TOP lptop; //接收文件头 lop0:intRet = recv(m_lp->m_sock,(char*)&lptop,sizeof(FILE_PACK_TOP),0); if(intRet == -1) { Sleep(500); goto lop0; } //客户端已断开 if(intRet == 0) { closesocket(m_lp->m_sock); delete m_lp; return FALSE; } //发送返回包 strcpy(chCheck,"OK"); intRet = send(m_lp->m_sock,chCheck,3,0); //包个数 int intPackCount = lptop.intCount; //创建临时内存区 FILE_TABLE *m_FileList = new FILE_TABLE; //文件名 strcpy(m_FileList->chFileName,lptop.chFileName); //发送者 strcpy(m_FileList->chFormUser,lptop.chFromUserName); //接收者 strcpy(m_FileList->chToUser,lptop.chToUserName); //初始化临界区 InitializeCriticalSection(&(m_FileList->gs_sec)); //必需接收的包数量 m_FileList->intPackCount = lptop.intCount; //数据还没准备好 m_FileList->intIs = 0; m_FileList->chBUF = NULL; //数据工作区大小 m_FileList->intBUFSize = 0; //发送者线程句柄NULL m_FileList->m_SendHandle = NULL; CCFileManager *m_FileMgr = CCFileManager::GetFileManager(); //文件加入至连表 m_FileMgr->AddFileList(m_FileList); //等待对方取走数据计数 int intWaitCount; while( intPackCount != 0 ) { ZeroMemory(chLen,10); //接收包长 lop1: intRet = recv(m_lp->m_sock,chLen,10,0); if(intRet == -1) { Sleep(100); goto lop1; } //若客户端关闭 if(0==intRet) { //对方已取消发送 m_FileList->intIs = 4; //用户已关闭连接 closesocket(m_lp->m_sock); //删除线程函数形参 delete m_lp; return 0; } //若已接收到包长 intPackLen = atoi(chLen); //临时数据内存区 m_FileList->chBUF = new char[intPackLen]; //数据包大小 m_FileList->intBUFSize = intPackLen; //已接收字节 intHavRecv = 0; while((intPackLen != intHavRecv) && ((CICQSApp*)AfxGetApp())->bolRuning) { lop2: intRet = recv(m_lp->m_sock,m_FileList->chBUF + intHavRecv,intPackLen -intHavRecv ,0); if(intRet == -1) { Sleep(100); goto lop2; } //若客户端关闭 if(intRet == 0) { //用户已关闭连接 closesocket(m_lp->m_sock); delete m_lp; //发送者线程存在 if(m_FileList->m_SendHandle != NULL) { //对方已取消发送 m_FileList->intIs = 4; }else //若发送者线程还没启动,则自删除结点 { m_FileMgr->DeleteFileNode(m_FileList); } //删除文件连表中的结点 //m_FileMgr->DeleteFileNode(m_FileList); return 0; } intHavRecv += intRet; } //数据已准备好,通知发送者发送数据 m_FileList->intIs = 1; //若对方在1分中内没取走数据则假设对方已关了客户端 intWaitCount = 0; WaitExist: if(m_FileList->m_SendHandle != NULL) { //唤醒发送者 ResumeThread(m_FileList->m_SendHandle); }else//线程还没启动 { intWaitCount++; if(intWaitCount <60) { Sleep(1000); goto WaitExist; }else //若等了1分钟还没有发送服务,则退出 { strcpy(chCheck,"NO"); //发送返回包 send(m_lp->m_sock,chCheck,3,0); //用户已关闭连接 closesocket(m_lp->m_sock); delete m_lp; m_FileMgr->DeleteFileNode(m_FileList); return 0; } } intWaitCount = 0; lop3: switch(m_FileList->intIs) { case 1://等发送者取走数据 { intWaitCount++; if(intWaitCount <60) { Sleep(200); goto lop3; }else//若在一分中内还没取走一个包就不要发送了 { strcpy(chCheck,"NO"); //发送返回包 send(m_lp->m_sock,chCheck,3,0); //用户已关闭连接 closesocket(m_lp->m_sock); delete m_lp; m_FileMgr->DeleteFileNode(m_FileList); return 0; } } break; case 3://对方取消了接收 { strcpy(chCheck,"NO"); //发送返回包 send(m_lp->m_sock,chCheck,3,0); //用户已关闭连接 closesocket(m_lp->m_sock); delete m_lp; m_FileMgr->DeleteFileNode(m_FileList); return 0; } break; } //发送返回包 send(m_lp->m_sock,chCheck,3,0); //包个数减1 intPackCount--; } //自删除结点 m_FileMgr->DeleteFileNode(m_FileList); AfxMessageBox("Exit Receive Thread"); closesocket(m_lp->m_sock); delete m_lp; return 0; } |
|
|
|
20
修改
删除
举报
引用
回复
| |