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

📄 filetransferdlg.cpp

📁 自己写的网络文件传输系统
💻 CPP
字号:
// FileTransferDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FileTransfer.h"
#include "FileTransferDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CFileTransferDlg dialog

CFileTransferDlg::CFileTransferDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CFileTransferDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CFileTransferDlg)
	m_strFilePath = _T("");
	m_strFileName = _T("");
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFileTransferDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CFileTransferDlg)
	DDX_Control(pDX, IDC_IPADDRESS, m_ctlIPAddress);
	DDX_Text(pDX, IDC_EDIT_PATH, m_strFilePath);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CFileTransferDlg, CDialog)
	//{{AFX_MSG_MAP(CFileTransferDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_RADIO_TRANS, OnRadioTrans)
	ON_BN_CLICKED(IDC_BROWCE, OnBrowce)
	ON_NOTIFY(IPN_FIELDCHANGED, IDC_IPADDRESS, OnFieldchangedIpaddress)
	ON_BN_CLICKED(IDC_START, OnStart)
	ON_BN_CLICKED(IDC_RADIO_ACCEPT, OnRadioAccept)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFileTransferDlg message handlers

BOOL CFileTransferDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	//Load winsock2 library
	WSADATA            wsd;
	if(WSAStartup(0x0202,&wsd)!=0)
	{
		MessageBox(_T("加载Winsock2库失败!"),_T("错误"),MB_ICONSTOP);
		return FALSE;
	}
	
	GetDlgItem(IDC_EDIT_PATH)->EnableWindow(FALSE);
	GetDlgItem(IDC_IPADDRESS)->EnableWindow(FALSE);
	GetDlgItem(IDC_BROWCE)->EnableWindow(FALSE);
	GetDlgItem(IDC_START)->EnableWindow(FALSE);	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFileTransferDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CFileTransferDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CFileTransferDlg::OnRadioTrans() 
{
	GetDlgItem(IDC_EDIT_PATH)->EnableWindow(TRUE);
	GetDlgItem(IDC_IPADDRESS)->EnableWindow(TRUE);
	GetDlgItem(IDC_BROWCE)->EnableWindow(TRUE);
}

void CFileTransferDlg::OnBrowce() 
{
	CFileDialog fOpenDlg(TRUE,NULL,NULL,OFN_SHOWHELP,NULL,this);
	if(fOpenDlg.DoModal()==IDOK)
	{
		m_strFilePath=fOpenDlg.GetPathName();
		m_strFileName=fOpenDlg.GetFileName();
		UpdateData(FALSE);
		if(m_ctlIPAddress.GetAddress(m_dwIP)==4)
			GetDlgItem(IDC_START)->EnableWindow(TRUE);
	}
}

void CFileTransferDlg::OnFieldchangedIpaddress(NMHDR* pNMHDR, LRESULT* pResult) 
{
    if(m_strFilePath!="")
		GetDlgItem(IDC_START)->EnableWindow(TRUE);		
	*pResult = 0;
}

void CFileTransferDlg::OnStart() 
{
	if(m_ctlIPAddress.GetAddress(m_dwIP)!=4)
	{
		MessageBox(_T("非法的IP地址!"),_T("错误"),MB_ICONSTOP);
		GetDlgItem(IDC_START)->EnableWindow(FALSE);
		return;
	}
	GetDlgItem(IDC_START)->EnableWindow(FALSE);
	
	SOCKET             sClient;
	struct sockaddr_in server;
	HANDLE             hFile;
	DWORD              dwFileSize;
	char               ACK[3];
	
	//创建套接字
	sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sClient==INVALID_SOCKET)
	{
		MessageBox(_T("套接字创建失败!"),_T("错误"),MB_ICONSTOP);
		return;
	}
	
	server.sin_family=AF_INET;
	server.sin_port=htons(PORT);
	server.sin_addr.S_un.S_addr=htonl(m_dwIP);
	
	//连接到目标主机
	if(connect(sClient,(struct sockaddr *)&server,sizeof(server))==SOCKET_ERROR)
	{
		MessageBox(_T("不能建立与指定主机的连接!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		return;
	}
	
	//创建文件句柄
	hFile=CreateFile(LPCSTR(m_strFilePath),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_HIDDEN,NULL);
	if(hFile==INVALID_HANDLE_VALUE)
	{
		MessageBox(_T("打开文件失败!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		return;
	}
	//得到文件长度
	dwFileSize=GetFileSize(hFile,NULL);

	//填充FILEINFO结构,并向对方发送文件信息(第一次握手)
	FILEINFO fInfo;
	strcpy(fInfo.FileName,LPCSTR(m_strFileName));
	fInfo.FileSize=dwFileSize;
	if(send(sClient,(char *)&fInfo,sizeof(FILEINFO),0)==SOCKET_ERROR)
	{
		MessageBox(_T("向对方发送数据失败!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		CloseHandle(hFile);
		return;
	}
	
	GetDlgItem(IDC_PROMPT)->SetWindowText("正在等待对方接收文件......");
	//等待对方主机的响应
	if(recv(sClient,ACK,3,0)==SOCKET_ERROR)
	{
		MessageBox(_T("接收数据时出现错误!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		CloseHandle(hFile);
		return;
	}

	//对方拒绝了文件的接收
	if(ACK[0]=='R')
	{
		GetDlgItem(IDC_PROMPT)->SetWindowText("对方拒绝了文件的接收!");
		closesocket(sClient);
		CloseHandle(hFile);
		return;
	}

	//对方主机发来ACK,可以传送文件了
	GetDlgItem(IDC_PROMPT)->SetWindowText("正在传送文件......");
	if(!TransmitFile(sClient,hFile,0,0,NULL,NULL,0))
	{
		MessageBox(_T("发送文件失败!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		CloseHandle(hFile);
		return;
	}
	
	GetDlgItem(IDC_PROMPT)->SetWindowText("文件发送成功");

	//关闭文件和套接字句柄
	CloseHandle(hFile);
	closesocket(sClient);
	GetDlgItem(IDC_START)->EnableWindow(TRUE);
}

void CFileTransferDlg::OnRadioAccept() 
{
    SOCKET             sListen,sClient;
	struct sockaddr_in local,Client;
	HANDLE             hFile;
	char               buffer[1024],ACK[3]={'A','C','K'},fileExt[5];
	int                ptExt,iAddrsize=sizeof(Client);
	DWORD              ret,nWritten=0,dwFileSize=0;
	
	//创建套接字
	sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sListen==INVALID_SOCKET)
	{
		MessageBox(_T("套接字创建失败!"),_T("错误"),MB_ICONSTOP);
		return;
	}
	
	local.sin_family=AF_INET;
	local.sin_port=htons(PORT);
	local.sin_addr.S_un.S_addr=htons(INADDR_ANY);
	//绑定端口
	if(bind(sListen,(struct sockaddr *)&local,sizeof(local))==SOCKET_ERROR)
	{
		MessageBox(_T("将套接字绑定到指定端口上出现错误!"),_T("错误"),MB_ICONSTOP);
		closesocket(sListen);
		return;
	}
	
	listen(sListen,1);
	GetDlgItem(IDC_PROMPT)->SetWindowText("正在等待发送端的连接请求......");
	//接收发送端的连接请求
	sClient=accept(sListen,(struct sockaddr *)&Client,&iAddrsize);
	if(sClient==INVALID_SOCKET)
	{
		MessageBox(_T("接收客户端套接字失败!"),_T("错误"),MB_ICONSTOP);
		closesocket(sListen);
		return;
	}	
	closesocket(sListen);
	
	//接收客户端发来的文件信息(第一次握手)
	FILEINFO fInfo;
	if(recv(sClient,(char *)&fInfo,sizeof(FILEINFO),0)==SOCKET_ERROR)
	{
		MessageBox(_T("接收数据时出现错误!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		return;
	}
	//得到文件的长度和扩展名
	dwFileSize=fInfo.FileSize;
	for(int i=0;fInfo.FileName[i]!='\0';i++)
	{
		if(fInfo.FileName[i]=='.')
			ptExt=i;
	}
	for(i=0;;i++)
	{
		fileExt[i]=fInfo.FileName[++ptExt];
		if(fileExt[i]=='\0')
			break;
	}
		
	

	//弹出文件保存对话框来选择路径
	CFileDialog fSaveDlg(FALSE,fileExt,fInfo.FileName,OFN_SHOWHELP|OFN_OVERWRITEPROMPT,NULL,this);
	if(fSaveDlg.DoModal()==IDCANCEL)
	{
		//取消了文件传送
		ACK[0]='R';
		ACK[1]='E';
		ACK[2]='J';
		if(send(sClient,ACK,3,0)==SOCKET_ERROR)
		{
			MessageBox(_T("发送响应时出现错误!"),_T("错误"),MB_ICONSTOP);
			closesocket(sClient);
			return;
		}
		GetDlgItem(IDC_PROMPT)->SetWindowText("文件接收被取消");
		closesocket(sClient);
		return;
	}
	m_strFilePath=fSaveDlg.GetPathName();

	//创建文件句柄
	hFile=CreateFile(LPCSTR(m_strFilePath),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	if(hFile==INVALID_HANDLE_VALUE)
	{
		MessageBox(_T("创建文件失败!"),_T("错误"),MB_ICONSTOP);
		closesocket(sClient);
		return;
	}
	
	GetDlgItem(IDC_PROMPT)->SetWindowText("正在接收文件......");
	//发送ACK
	if(send(sClient,ACK,3,0)==SOCKET_ERROR)
	{
		MessageBox(_T("发送响应时出现错误!"),_T("错误"),MB_ICONSTOP);
		CloseHandle(hFile);
		closesocket(sClient);
		return;
	}
	//开始接收文件
	while(dwFileSize>0)
	{
		ret=recv(sClient,buffer,1024,0);
		if(ret==SOCKET_ERROR)
		{
			MessageBox(_T("接收数据时出现错误!"),_T("错误"),MB_ICONSTOP);
			CloseHandle(hFile);
			closesocket(sClient);
			return;
		}
		dwFileSize-=ret;
		WriteFile(hFile,buffer,ret,&nWritten,NULL);
		if(nWritten!=ret)
		{
			MessageBox(_T("写文件时出现错误!"),_T("错误"),MB_ICONSTOP);
			CloseHandle(hFile);
			closesocket(sClient);
			return;
		}
	}

	GetDlgItem(IDC_PROMPT)->SetWindowText("文件接收成功!");
	//关闭文件和套接字句柄
	CloseHandle(hFile);
	closesocket(sClient);
}

void CFileTransferDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	WSACleanup();
}

⌨️ 快捷键说明

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