📄 filetransferdlg.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 + -