📄 dspfile.cpp
字号:
// DSPFile.cpp: implementation of the DSPFile class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DSPFile.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
enum
{
SEND_SUCCESSFUL=100,
RECV_SUCCESSFUL,
SEND_TIMEOUT,
RECV_TIMEOUT,
SEND_FAIL,
RECV_FAIL,
SEND_ABORT,
RECV_ABORT,
};
DSPFile::DSPFile()
{
}
DSPFile::~DSPFile()
{
if(this->m_ifs.is_open())
this->m_ifs.close();
if(this->m_ofs.is_open())
{
this->m_ofs.flush();
this->m_ofs.close();
}
}
bool DSPFile::Serialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp)
{
switch(byAttrNo)
{
case 1:
dsp.Write(this->m_nFilesize);
return false;
case 2:
dsp.Write(this->m_strFilename);
return false;
case 3: //序列化最后一个属性
if(this->m_ifs.is_open()==FALSE)
{
//打开文件准备读
if(DSP::OpenIfstreamForRead(this->m_ifs,this->m_hFileDetail.strPathname)==FALSE)
{
//如果打开文件失败
dsp.Write(NULL,0,true);
return true;
}
}
else
{
//如果文件已经读完
this->m_ifs.close();
}
dsp.Write(this->m_buff,FILE_SECT_SIZE,false);
}
return true;
}
bool DSPFile::UnSerialize(BYTE byClassLevels,BYTE byAttrNo,DSP::_DSPPACKET &dsp,DWORD dwLen)
{
//反序列化对象
switch(byAttrNo)
{
case 1:
dsp.Read(this->m_nFilesize);
return false;
case 2:
dsp.Read(this->m_strFilename,dwLen);
return false;
case 3: //序列化最后一个属性
if(this->m_ofs.is_open()==FALSE)
{
this->m_hFileDetail.strPathname =this->m_strFilename.c_str();
this->m_hFileDetail.nFilesize =this->m_nFilesize;
this->m_hFileDetail.nCurrLen =FILE_SECT_SIZE;
//传送文件名和尺寸,并且打开文件输出流,准备写
::SendMessage(this->m_hFileDetail.hwnd,MSG_SETFILENAMESIZE,
(WPARAM)&this->m_hFileDetail,0);
//打开对话框,选择被保存的文件名
CFileDialog fileDialog(FALSE,NULL,this->m_strFilename.c_str(),OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT);
if(fileDialog.DoModal()==IDOK)
{
//得到被选择的文件名
this->m_hFileDetail.strPathname =fileDialog.GetPathName();
//重新传送文件名和尺寸
::SendMessage(this->m_hFileDetail.hwnd,MSG_SETFILENAMESIZE,
(WPARAM)&this->m_hFileDetail,0);
this->m_hFileDetail.nCurrLen =0;
if(DSP::OpenOfstreamForWrite(this->m_ofs,this->m_hFileDetail.strPathname)==FALSE)
{
//如果找开文件失败
dsp.Read(NULL,0);
return true;
}
}
else
{
dsp.Read(NULL,0);
return true;
}
}
else
{
//文件已经写完
this->m_ofs.flush();
this->m_ofs.close();
}
dsp.Read(this->m_buff,dwLen);
}
return true;
}
bool DSPFile::AttrSectRecv(BYTE byClassLevels,BYTE byAttrNo,const char* const lpBuff,DWORD dwLen,bool bLast)
{
this->m_ofs.write(lpBuff,dwLen);
this->m_hFileDetail.nCurrLen +=dwLen;
::SendMessage(this->m_hFileDetail.hwnd,MSG_RECVSECT,(WPARAM)&this->m_hFileDetail,dwLen);
return true;
}
bool DSPFile::AttrSectSend(BYTE byClassLevels,BYTE byAttrNo,char** const lpBuff,DWORD& dwLen,bool& bContinue)
{
this->m_ifs.read(*lpBuff,dwLen);
if(this->m_ifs.eof())
{
//如果文件已经结束
//得到文件的大小
int size =this->m_ifs.tellg();
//得到最后读取的文件尺寸,设定最后接收的字节数
dwLen =size%dwLen;
//设定不需要再继续接收
bContinue =false;
}
this->m_hFileDetail.nCurrLen +=dwLen;
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDSECT,(WPARAM)&this->m_hFileDetail,dwLen);
return true;
}
bool DSPFile::ReadySendFile(bool& bRun,SOCKET sock,bool bCrc,DSP::_DSPPACKET& packet,HWND hWnd)
{
// TODO: Add your control notification handler code here
//开始传送文件线程
CFileDialog fileDialog(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_FILEMUSTEXIST);
if(fileDialog.DoModal()==IDOK)
{
//得到被选择的包含路径的文件名
this->m_hFileDetail.strPathname =fileDialog.GetPathName();
//得到被选择的文件名
this->m_strFilename =fileDialog.GetFileName();
//得到文件的大小
HANDLE fileHandle =::CreateFile(this->m_hFileDetail.strPathname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
this->m_nFilesize =::GetFileSize(fileHandle,NULL);
::CloseHandle(fileHandle);
//保存文件尺寸到结构中
this->m_hFileDetail.nFilesize =this->m_nFilesize;
//初始化传送文件的步长
this->m_hFileDetail.nCurrLen =FILE_SECT_SIZE;
//初始化值
this->m_hFileDetail.hwnd =hWnd;
this->m_hFileDetail.lpbRun =&bRun;
bRun =true;
//通知准备传送的文件名和尺寸
::SendMessage(this->m_hFileDetail.hwnd,MSG_SETFILENAMESIZE,(WPARAM)&this->m_hFileDetail,0);
//初始化传送文件的尺寸
this->m_hFileDetail.nCurrLen =0;
//设置等待时间为10分钟
packet.Timeout.tv_sec =600;
packet.SetParameter(FALSE,bCrc);
//序列化对象
if(packet.WriteObject(sock,*this))
{
//传送完成
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,SEND_SUCCESSFUL);
return true;
}
else
{
if(bRun)
{
//传送失败,可能是对方放弃或传送失败或超时
DSP::_DSPERROR* lphErr =packet.GetLastError();
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,
(lphErr->nErrorNo==DSP::ERR_SEND_HEADER)?SEND_TIMEOUT:SEND_FAIL);
}
else
{
//如果是点击了放弃按钮
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,SEND_ABORT);
}
}
}
return false;
}
bool DSPFile::ReadyRecvFile(bool& bRun,SOCKET sock,DSP::_DSPPACKET& packet,HWND hWnd)
{
//设置放充的布尔变量,改变该变量的值,可以立即中止传送,初始化为允许接收
bRun =true;
this->m_hFileDetail.lpbRun =&bRun;
//设置进行消息传递的窗体的句柄
this->m_hFileDetail.hwnd =hWnd;
while(true)
{
if(packet.ReadObject(sock,this))
{
//接收完成
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,RECV_SUCCESSFUL);
}
else
{
if(bRun)
{
//接收失败,可能是对方放弃或接收数据时失败或超时
DSP::_DSPERROR* lphErr =packet.GetLastError();
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,
(lphErr->nErrorNo==DSP::ERR_RECV_HEADER)?RECV_TIMEOUT:RECV_FAIL);
}
else
{
//如果是接收被放弃
::SendMessage(this->m_hFileDetail.hwnd,MSG_SENDCOMPLETE,(WPARAM)&this->m_hFileDetail,RECV_ABORT);
}
return false;
}
}
}
bool DSPFile::GetCompleteInfo(int which, CString &str)
{
switch(which)
{
case SEND_SUCCESSFUL:
str ="传送文件成功!";
return true;
case RECV_SUCCESSFUL:
str ="接收文件成功!";
return true;
case SEND_TIMEOUT:
str ="传送文件超时或对方关闭了连接!";
break;
case RECV_TIMEOUT:
str ="接收文件超时或对方关闭了连接!";
break;
case SEND_FAIL:
str ="传送文件失败,可能是连接被中断或超时!";
break;
case RECV_FAIL:
str ="接收文件失败,可能是连接被中断或超时,或接收到了不正确的信息!";
break;
case SEND_ABORT:
str ="传送文件过程被中止!";
break;
case RECV_ABORT:
str ="接收文件过程被中止!";
break;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -