⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filetransfersdlg.cpp

📁 一个文件传输的例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		m_nTimer = SetTimer(1, 50000, NULL);
	}
}

void CFileTransfersDlg::OnStopTransfers() 
{	
	if(m_bIsWait)
	{
		if(MessageBox(_T("真的要停止等待吗?"), _T("警告"), MB_ICONEXCLAMATION|MB_YESNO) == IDYES)
		{
			m_bIsWait = FALSE;
			if(!m_bIsClient)
			{
				//停止ID为2的计时器
				if(KillTimer(2))
				{
					//结束监听
					CSocket sockClient;
					sockClient.Create();
					sockClient.Connect(_T("127.0.0.1"), m_wPort + PORT);
					sockClient.Close();
				}
			}
			else
			{
				//停止ID为1的计时器
				if(KillTimer(1))
				{					
					//告诉对方发送等待被取消
					CMessage* pMsg = new CMessage(CANCEL);
					m_psockClient->SendMsg(pMsg);
					
					GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
					GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
					GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
				}
			}
		}
		return ;
	}
	
	if(MessageBox(_T("真的要停止文件传输吗?"), _T("警告"), MB_ICONEXCLAMATION|MB_YESNO) == IDYES)
	{
		m_bIsStop = TRUE;
		return ;
	}
}

int CFileTransfersDlg::GetLocalHostInfo(CString &strHostName, CString &strIPAddress)
{
	char szHostName[256];
	
	if(gethostname(szHostName, sizeof(szHostName)))
	{
		strHostName = _T("");
		MessageBox(GetError(GetLastError()), _T("错误"), MB_ICONHAND|MB_OK);
		return -1;
	}
	
	PHOSTENT hostinfo;
	if((hostinfo = gethostbyname(szHostName)) == NULL)
		return GetLastError();
	
	LPCSTR ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
	
	strIPAddress = ip;
	strHostName = szHostName;
	
	return 0;
}

CString CFileTransfersDlg::GetError(DWORD error)
{
	CString strError;
	switch(error)
	{
	case WSANOTINITIALISED:
		strError="初始化错误";
		break;
	case WSAENOTCONN:
		strError="对方没有启动";
		break;
	case WSAEWOULDBLOCK :
		strError="对方已经关闭";
		break;
	case WSAECONNREFUSED:
		strError="连接的尝试被拒绝";
		break;
	case WSAENOTSOCK:
		strError="在一个非套接字上尝试了一个操作";
		break;
	case WSAEADDRINUSE:
		strError="特定的地址已在使用中";
		break;
	case WSAECONNRESET:
		strError="与主机的连接被关闭";
		break;
	default:
		strError="一般性错误";	
	}
	return strError;
}

void CFileTransfersDlg::ProcessAccept()
{
	CClientSocket* pSocket = new CClientSocket(this);
	//将请求接收下来,得到一个新的套接字pSocket
	if(m_psockServer->Accept(*pSocket))
	{
		//初始化套接字pSocket
		pSocket->Init();
		
		CMessage* pMsg;
		//如果m_psockClient套接字为空,则表示还没有和任何客户端建立连接
		if(m_psockClient == NULL)
		{
			//向客户端发送一个消息,表示连接被接受
			pMsg = new CMessage(CONNECT_BE_ACCEPT);
			pSocket->SendMsg(pMsg);
			m_psockClient = pSocket;
			
			GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
		}
		else
		{
			//否则向客户端发一个信息,服务器已经存在连接
			pMsg = new CMessage(CONNECT_BE_REFUSE);
			pSocket->SendMsg(pMsg);
		}
	}
}

void CFileTransfersDlg::ProcessReceive(CClientSocket* pSocket)
{
	//获取信息
	CMessage* pMsg = new CMessage();
	pSocket->ReceiveMsg(pMsg);
	
	//当消息类型为连接被接受时执行该if语句里面的内容
	if(pMsg->m_nType == CONNECT_BE_ACCEPT)
	{
		GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
		return;
	}

	//当消息类型为连接被拒绝时执行该if语句里面的内容
	if(pMsg->m_nType == CONNECT_BE_REFUSE)
	{
		MessageBox(_T("服务器已经和另外的客户端建立连接,请等一下再连接。"), _T("错误"), MB_ICONHAND);
		
		delete m_psockClient;
		m_psockClient = NULL;
		
		GetDlgItem(IDC_RADIO_SERVER)->EnableWindow(TRUE);
		GetDlgItem(IDC_RADIO_CLIENT)->EnableWindow(TRUE);
		GetDlgItem(IDC_IPADDRESS)->EnableWindow(TRUE);
		GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
		GetDlgItem(IDC_BEGIN)->EnableWindow(TRUE);
		GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
		return ;
	}
	
	//当消息类型为连接被断开时执行该if语句里面的内容
	if(pMsg->m_nType == DISCONNECT)
	{
	//	MessageBox(_T("对方已经关闭"), _T("警告"), MB_ICONHAND);
		
		if(m_psockClient != NULL)
		{
			delete m_psockClient;
			m_psockClient = NULL;
		}
		
		if(m_nServerType == CLIENT)
		{	
			GetDlgItem(IDC_RADIO_SERVER)->EnableWindow(TRUE);
			GetDlgItem(IDC_RADIO_CLIENT)->EnableWindow(TRUE);
			GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
			GetDlgItem(IDC_BEGIN)->EnableWindow(TRUE);
			GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
			GetDlgItem(IDC_SELECT_FILE)->EnableWindow(FALSE);
			GetDlgItem(IDC_IPADDRESS)->EnableWindow(TRUE);
		}
		else
		{
			GetDlgItem(IDC_SELECT_FILE)->EnableWindow(FALSE);
		}
		return ;
	}

	//当收到传输文件请求时执行该if语句里面的内容
	if(pMsg->m_nType == REQUEST)
	{
		m_bIsWait = TRUE;
		
		m_strFileName = pMsg->m_strFileName;
		m_dwFileSize = pMsg->m_dwFileSize;
		
		//CFileDialog dlg(FALSE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件 (*.*)|*.*||", this);
		//dlg.m_ofn.lpstrTitle = _T("另存为");
		//strcpy(dlg.m_ofn.lpstrFile, m_strFileName.GetBuffer(m_strFileName.GetLength()));
		CString a;
		a=m_strFileName;
//		if(dlg.DoModal() == IDOK)
//		{
			if(m_bIsWait == FALSE)
			{
				MessageBox(_T("对方已经取消文件发送"), _T("警告"), MB_ICONEXCLAMATION);
				return ;
			}
			
			m_bIsClient = FALSE;
			//m_strPath = dlg.GetPathName();
            m_strPath="d:\\file\\"+a;
	
			GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
			GetDlgItem(IDC_SELECT_FILE)->EnableWindow(FALSE);
			GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(TRUE);
			
			m_strFileSize.Format("%ld 字节", m_dwFileSize);
		//	GetDlgItem(IDC_FILE_NAME)->SetWindowText(dlg.GetFileName());
            GetDlgItem(IDC_FILE_NAME)->SetWindowText(a);
			GetDlgItem(IDC_FILE_SIZE)->SetWindowText(m_strFileSize);
			GetDlgItem(IDC_TRANSFERS_TIP)->SetWindowText(_T("已收到:"));
			
			//启动接收文件的线程
			pThreadListen = ::AfxBeginThread(_ListenThread, this);
			return ;
	//	}
		
		if(m_bIsWait == TRUE)
		{		
			//告诉对方文件发送请求被拒绝
			CMessage* pMsg = new CMessage(REFUSE);
			m_psockClient->SendMsg(pMsg);
		}
		
		m_bIsWait = FALSE;
		return ;
	}

	//当对方同意且准备好接收文件时执行该if语句里面的内容
	if(pMsg->m_nType == ACCEPT)
	{	
		KillTimer(1);
		m_bIsWait = FALSE;
		//启动文件发送线程
		pThreadSend = ::AfxBeginThread(_SendThread, this);
		return ;
	}
	
	//当发送文件请求被拒绝时执行该if语句里面的内容
	if(pMsg->m_nType == REFUSE)
	{	
		m_bIsWait = FALSE;
		
		MessageBox(_T("请求被拒绝"), _T("警告"), MB_ICONEXCLAMATION);
		
		GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
		GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
		GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
		return ;
	}

	//当对方取消文件传输时执行该if语句里面的内容
	if(pMsg->m_nType == CANCEL)
	{
		m_bIsWait = FALSE;
		return ;
	}
	
	return ;
}

void CFileTransfersDlg::SendFile(CSocket &senSo)
{
	m_bIsTransmitting = TRUE;

	//打开要发送的文件
	CFile file;
	if(!file.Open(m_strPath, CFile::modeRead | CFile::typeBinary))
	{
		AfxMessageBox(_T("文件打开失败"));
		
		GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
		GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
		GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
		
		senSo.Close();
		
		return ;
	}
	
	m_ctrlProgress.SetRange32(0, m_dwFileSize);
	
	int nSize = 0, nLen = 0;
	DWORD dwCount = 0;
	char buf[BLOCKSIZE] = {0};
	file.Seek(0, CFile::begin);
	//开始传送文件
	for(;;)
	{
		//一次读取BLOCKSIZE大小的文件内容
		nLen = file.Read(buf, BLOCKSIZE);
		if(nLen == 0)
			break;
		
		//发送文件内容
		nSize = senSo.Send(buf, nLen);
		
		dwCount += nSize;
		m_ctrlProgress.SetPos(dwCount);
		CString strTransfersSize;
		strTransfersSize.Format("%ld 字节", dwCount);
		GetDlgItem(IDC_RECEIVE_SIZE)->SetWindowText(strTransfersSize);
		
		if(m_bIsStop)
		{
			m_bIsStop = FALSE;
			break;
		}
		
		if(nSize == SOCKET_ERROR)
			break;
	}
	//关闭文件
	file.Close();
	//关闭套接字
	senSo.Close();
	
	if(m_dwFileSize == dwCount)
		AfxMessageBox(_T("文件发送成功"));
	else
		AfxMessageBox(_T("文件发送失败"));
	
	m_ctrlProgress.SetPos(0);
	GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
	GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
	GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);

	m_bIsTransmitting = FALSE;	
}

void CFileTransfersDlg::ReceiveFile(CSocket &recSo)
{
	//停止等待超时计时器
	KillTimer(2);
	m_bIsWait = FALSE;
	m_bIsTransmitting = TRUE;
	
	m_ctrlProgress.SetRange32(0, m_dwFileSize);
	GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
	GetDlgItem(IDC_SELECT_FILE)->EnableWindow(FALSE);
	GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(TRUE);
	
	int nSize = 0;
	DWORD dwCount = 0;
	char buf[BLOCKSIZE] = {0};	
	//创建一个文件
	CFile file(m_strPath, CFile::modeCreate|CFile::modeWrite);
	//开始接收文件
	for(;;)
	{
		//每次接收BLOCKSIZE大小的文件内容
		nSize = recSo.Receive(buf, BLOCKSIZE);
		if(nSize == 0)
			break;
		
		//将接收到的文件写到新建的文件中去
		file.Write(buf, nSize);
		dwCount += nSize;
		m_ctrlProgress.SetPos(dwCount);
		CString strTransfersSize;
		strTransfersSize.Format("%ld 字节", dwCount);
		GetDlgItem(IDC_RECEIVE_SIZE)->SetWindowText(strTransfersSize);
		
		//用户是否要停止接收
		if(m_bIsStop)
		{
			m_bIsStop = FALSE;
			break;
		}
	}
	//关闭文件
	file.Close();
	//关闭套接字
	recSo.Close();
	
//	if(m_dwFileSize == dwCount)
//		AfxMessageBox(_T("文件接收成功"));
//	else
//		AfxMessageBox(_T("文件接收失败"));
	
	m_ctrlProgress.SetPos(0);
	GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
	GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
	GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
	
	m_bIsTransmitting = FALSE;
}

void CFileTransfersDlg::TransfersFailed()
{
	GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
	GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
	GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
}

LRESULT CFileTransfersDlg::OnAcceptTransfers(WPARAM wParam, LPARAM lParam)
{	
	//告诉对方文件请求被接受且准备好接收	
	CMessage* pMsg = new CMessage(ACCEPT);
	m_psockClient->SendMsg(pMsg);
	//设置一个ID为2的超时计时器
	m_nTimer = SetTimer(2, 5000, NULL);
	return 0;
}

void CFileTransfersDlg::OnTimer(UINT nIDEvent) 
{
	switch(nIDEvent)
	{
	//ID为1的计时器
	case 1:
		{
			//结束ID为1的计时器
			KillTimer(1);
			m_bIsWait = FALSE;
			
			//告诉对方发送等待被取消
			CMessage* pMsg = new CMessage(CANCEL);
			m_psockClient->SendMsg(pMsg);
			
			MessageBox(_T("等待超时"), _T(" 警告"), MB_ICONEXCLAMATION);
			
			GetDlgItem(IDC_DISCONNECT)->EnableWindow(TRUE);
			GetDlgItem(IDC_SELECT_FILE)->EnableWindow(TRUE);
			GetDlgItem(IDC_STOP_TRANSFERS)->EnableWindow(FALSE);
			break;
		}
	//ID为2的计时器
	case 2:
		{
			//结束ID为2的计时器
			KillTimer(2);
			//结束监听
			CSocket sockClient;
			sockClient.Create();
			sockClient.Connect(_T("127.0.0.1"), m_wPort + PORT);
			sockClient.Close();
			break;
		}
	}
	
	CDialog::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -