//1:显示文件进度
//2:可以随时终止传输过程
//发送数据线程
UINT SendDataThread(LPVOID lpParam);
//接收数据线程
UINT ReceiveDataThread(LPVOID lpParam);
//发送数据按钮消息响应函数
void CTzg004Dlg::OnButtonSend()
{
// TODO: Add your control notification handler code here
//初始化数据发送结束标志
m_bSendEnd=FALSE;
//初始化数据接收结束标志
m_bRecEnd=FALSE;
//更新对话框数据
UpdateData(TRUE);
//打开文件对话框
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"所有文件 (*.*)|*.*||");
if(dlg.DoModal()==IDOK)
{
m_strFileName=dlg.GetPathName();
//开始发送数据线程
AfxBeginThread(SendDataThread,this,THREAD_PRIORITY_NORMAL);
}
}
//接收数据按钮消息响应函数
void CTzg004Dlg::OnButtonReceive()
{
// TODO: Add your control notification handler code here
//初始化数据发送结束标志
m_bSendEnd=FALSE;
//初始化数据接收结束标志
m_bRecEnd=FALSE;
UpdateData(TRUE);
//开始接收数据线程
AfxBeginThread(ReceiveDataThread,this,THREAD_PRIORITY_NORMAL);
}
//终止发送按钮消息响应
void CTzg004Dlg::OnButtonSendEnd()
{
// TODO: Add your control notification handler code here
//设置发送数据结束标志
m_bSendEnd=TRUE;
}
//终止接收按钮消息响应
void CTzg004Dlg::OnButtonRecEnd()
{
// TODO: Add your control notification handler code here
//设置接收数据结束标志
m_bRecEnd=TRUE;
}
UINT SendDataThread(LPVOID lpParam)
{
CTzg004Dlg *pDlg=(CTzg004Dlg *)lpParam;
CFile file;
if( !file.Open(pDlg->m_strFileName, CFile::modeRead) )
{
AfxMessageBox("打开文件出错!");
return 0;
}
CSocket sockTemp;
CString str,str1;
sockTemp.Create(pDlg->m_iDataPort1); //得到端口号
sockTemp.Listen(1);//只接受一个连接
CSocket sockSend;
//设置发送按钮禁止
pDlg->GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(FALSE);
sockTemp.Accept(sockSend);//注意,sockTemp已交了自己的指针地址到sockSend,故不用Close
//打开发送终止按钮
pDlg->GetDlgItem(IDC_BUTTON_SEND_END)->EnableWindow(TRUE);
int iBufSize = 1024 * 5;
int iSize = iBufSize;
LPBYTE pBuf = new BYTE[iBufSize];
DWORD dwTemp = 0;
BOOL bTest = sockSend.AsyncSelect(0);//由于CSocket实际是异步,将它变为同步(阻塞)方式。
sockSend.IOCtl( FIONBIO, &dwTemp);//用IOCtl要将AsyncSelect的第一个参数为0,参看MSDN
UINT uiLength = file.GetLength();
sockSend.Send(&uiLength, 4);//传送文件大小到接收方(Client端)
int iNumByte;
UINT uiTotal = 0;
while(uiTotal < uiLength)
{
int iEnd=pDlg->m_bSendEnd;
//传送发送端状态(是否结束)
iNumByte = sockSend.Send(&iEnd, sizeof(int));
//发送错误
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("发送错误!");
goto ExitLable1;
}else if(iEnd==1)//发送端终止
{
AfxMessageBox("发送端终止");
goto ExitLable1;
}
//读取文件内容
if((int)(uiLength - uiTotal) < iBufSize)
iSize = uiLength - uiTotal;//当小于缓冲区iTEST时的处理
iSize=file.Read(pBuf , iSize);//得到读取的字节数
int iCount=0;
//发送定长文件数据
while(iCount<iSize)
{
iNumByte = sockSend.Send(pBuf, iSize-iCount);//注意iNumByte为实际的发送字节数,不要以iSize为准
if(iNumByte == SOCKET_ERROR)
{
AfxMessageBox("发送错误!");
goto ExitLable1;
}
iCount+=iNumByte;
if(iCount<iSize)
{
file.Seek(iSize-iCount,CFile::current);
}
}
uiTotal += iCount;
//设置发送数据进度条
pDlg->m_CtrlProgressSend.SetPos(int(((double)uiTotal/uiLength)*100));
str.Format("发送进度:%d%%",int(((double)uiTotal/uiLength)*100));
//表明发送数据百分比
pDlg->GetDlgItem(IDC_STATIC_SEND)->GetWindowText(str1);
if(str1!=str)
pDlg->GetDlgItem(IDC_STATIC_SEND)->SetWindowText(str);
}
//发送文件成功
AfxMessageBox("发送文件成功!");
ExitLable1:
delete[] pBuf;
file.Close();
sockSend.Close();
pDlg->m_CtrlProgressSend.SetPos(0);//恢复进度
pDlg->GetDlgItem(IDC_BUTTON_SEND_END)->EnableWindow(FALSE);//设置发送结束按钮禁止
pDlg->GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(TRUE);//设置发送按钮正常
pDlg->GetDlgItem(IDC_STATIC_SEND)->SetWindowText("发送进度:"); //恢复提示进度
return 0;
}
本文地址:http://com.8s8s.com/it/it1347.htm