📄 fileposterdlg.cpp
字号:
//Download by http://www.NewXing.com
// FilePosterDlg.cpp : implementation file
//
#include "stdafx.h"
#include "FilePoster.h"
#include "FilePosterDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
CString m_dsc;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
m_dsc = _T("本程序运用UDP原理进行文件的传输,文件被分割为256B的数据块,为保证数据块的传输顺序,采用自定义Windows消息进行同步,即每接受完一个数据块给出一个消息,发送法受到消息后发送数据。");
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Text(pDX, IDC_EDIT, m_dsc);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFilePosterDlg dialog
int CFilePosterDlg::nFileSize = 0;
CFilePosterDlg::CFilePosterDlg(CWnd* pParent /*=NULL*/)
: CDialog(CFilePosterDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CFilePosterDlg)
m_filePath = _T("");
m_recv = _T("接受进度:");
m_send = _T("发送进度:");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_file = NULL;
m_posting = false;
}
void CFilePosterDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFilePosterDlg)
DDX_Control(pDX, IDC_PROGRESS_RECV, m_progress_r);
DDX_Control(pDX, IDC_PROGRESS_SEND, m_progress);
DDX_Control(pDX, IDC_IP_ADDR, m_IPAddr);
DDX_Text(pDX, IDC_FILE_PATH, m_filePath);
DDX_Text(pDX, IDC_RECV, m_recv);
DDX_Text(pDX, IDC_SEND, m_send);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CFilePosterDlg, CDialog)
//{{AFX_MSG_MAP(CFilePosterDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_FIND_FILE, OnFindFile)
ON_COMMAND(ID_MENU_SEND, OnMenuSend)
ON_COMMAND(ID_MENU_QUIT, OnMenuQuit)
ON_COMMAND(ID_ABOUT, OnAbout)
ON_COMMAND(ID_MENU_FIND, OnMenuFind)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_READY_TO_RECEIVE, OnReadyToRecv) //自定义消息,用于分块发送文件
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFilePosterDlg message handlers
struct RECVPARAM
{
HWND hWnd;
SOCKET sock;
};
BOOL CFilePosterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// m_progress.SetRange(0, 10000);
// m_progress_r.SetRange(0, 10000);
m_progress.SetStep(1);
m_progress_r.SetStep(1);
/***********************************************************************/
m_socket=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==m_socket)
{
MessageBox("套接字创建失败!");
return FALSE;
}
SOCKADDR_IN addrSock;
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(6800);
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
int retval;
retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
if(SOCKET_ERROR==retval)
{
closesocket(m_socket);
MessageBox("绑定失败!");
return FALSE;
}
//产生一个用于接收数据的线程
struct RECVPARAM *pRecvParam=new RECVPARAM;
pRecvParam->sock=m_socket;
pRecvParam->hWnd=m_hWnd;
HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread);
/**************************************************************************/
return TRUE; // return TRUE unless you set the focus to a control
}
void CFilePosterDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// 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 CFilePosterDlg::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();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CFilePosterDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//接收线程的回调函数
DWORD WINAPI CFilePosterDlg::RecvProc(LPVOID lpParameter)
{
SOCKET sock=((RECVPARAM*)lpParameter)->sock;
HWND hWnd=((RECVPARAM*)lpParameter)->hWnd;
delete lpParameter;
SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);
char recvBuf[0x112]; //256+17字节的缓冲
char fileName[0x100];
int retval, i;
FILE* file = NULL;
while(TRUE)
{
retval=recvfrom(sock,recvBuf,0x112,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR == retval)
break;
if (recvBuf[0] == 'R')
{
char wParam = 'R';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, 0);
}
else if (recvBuf[0] == 'D')
{
char wParam = 'D';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, 0);
}
else if (recvBuf[0] == 'H')
{
for (i = 1; i <= 0x100 && recvBuf[i] != '\0'; i++) //前256字节用于存储文件名
fileName[i-1] = recvBuf[i];
fileName[i-1] = '\0';
CString recvMsg;
nFileSize = atoi(&recvBuf[0x101]);
recvMsg.Format("收到来自于(%s)的文件:%s\n文件大小:%i字节\n是否接收?",
inet_ntoa(addrFrom.sin_addr), fileName, nFileSize);
if (IDOK == AfxMessageBox(recvMsg, MB_OKCANCEL))
{
CFileDialog saveDlg(false, NULL, fileName);
if (IDOK == saveDlg.DoModal())
{
if (!(file = fopen(saveDlg.GetPathName(), "wb")))
{
AfxMessageBox("创建本地文件失败!");
continue;
}
char wParam = 'H';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);
}
else
{
char wParam = 'C';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);
}
}
else
{
char wParam = 'C';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);
}
}
else if (recvBuf[0] == 'F')
{
fwrite(&recvBuf[0x12], 1, 0x100, file);
char wParam = 'F';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);
}
else if (recvBuf[0] == 'E')
{
int bufSize = atoi(&recvBuf[1]);
fwrite(&recvBuf[0x12], 1, bufSize, file);
fclose(file);
char wParam = 'E';
::PostMessage(hWnd, WM_READY_TO_RECEIVE, (WPARAM)&wParam, (LPARAM)&addrFrom);
}
else
AfxMessageBox("传送数据过程中出现错误!");
}
return (DWORD)NULL;
}
//调出打开对话框查找要发送的文件
void CFilePosterDlg::OnFindFile()
{
CFileDialog openFile(true);
if (IDOK == openFile.DoModal())
{
m_filePath = openFile.GetPathName();
UpdateData(false);
}
}
//按下发送键,发出文件信息
void CFilePosterDlg::OnOK()
{
if (m_posting)
{
MessageBox("数据发送中,请稍候再试。");
return;
}
UpdateData();
if (m_filePath == "")
{
MessageBox("请输入要发送的文件路径!");
return;
}
if (m_IPAddr.IsBlank())
{
MessageBox("请添入接收者的IP地址。");
return;
}
WIN32_FIND_DATA FindFileData;
if (INVALID_HANDLE_VALUE == FindFirstFile(m_filePath, &FindFileData))
{
MessageBox("文件路径错误或文件不存在!\n请重新指定文件路径。");
return;
}
DWORD dwIP;
m_IPAddr.GetAddress(dwIP);
SOCKADDR_IN addrTo;
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6800);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
char sendBuf[0x112];
int i;
sendBuf[0] = 'H';
for (i = 1; i <= 0x100 && FindFileData.cFileName[i-1] != '\0'; i++)
sendBuf[i] = FindFileData.cFileName[i-1];
sendBuf[i] = '\0';
_itoa(FindFileData.nFileSizeLow, &sendBuf[0x101], 10);
sendBuf[0x111] = '\0';
sendto(m_socket, sendBuf, 0x112, 0,
(SOCKADDR*)&addrTo, sizeof(SOCKADDR));
if (!(m_file = fopen(m_filePath, "rb")))
{
MessageBox("读取文件失败!");
}
m_nSend = 0;
m_nFileSize_s = FindFileData.nFileSizeLow;
m_progress.SetRange(0, m_nFileSize_s/0x100+1);
m_posting = true;
}
//消息响应函数,每响应一次发送一段数据
void CFilePosterDlg::OnReadyToRecv(WPARAM wParam,LPARAM lParam)
{
char sendBuf[0x112];
DWORD dwIP;
m_IPAddr.GetAddress(dwIP);
SOCKADDR_IN addrTo;
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6800);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
int nRead;
switch (*(char*)wParam)
{
case 'D':
MessageBox("对方拒绝接受你发送的文件!");
fclose(m_file);
m_posting = false;
break;
case 'R':
nRead = fread(&sendBuf[0x12], 1, 0x100, m_file);
if (nRead < 0x100)
{
sendBuf[0] = 'E';
_itoa(nRead, &sendBuf[1], 10);
sendto(m_socket, sendBuf, nRead+0x12, 0,
(SOCKADDR*)&addrTo, sizeof(SOCKADDR));
fclose(m_file);
m_progress.SetPos(m_nFileSize_s/0x100+1);
m_posting = false;
m_send = "发送进度:(100%)";
UpdateData(false);
MessageBox("发送完毕!");
m_progress.SetPos(0);
m_send = "发送进度:";
UpdateData(false);
}
else
{
sendBuf[0] = 'F';
sendto(m_socket, sendBuf, 0x112, 0,
(SOCKADDR*)&addrTo, sizeof(SOCKADDR));
m_progress.StepIt();
m_nSend++;
m_send.Format("发送进度:(%.1f%%)", (float)m_nSend/(m_nFileSize_s/0x100+1)*100);
UpdateData(false);
}
break;
case 'H':
m_progress_r.SetRange(0, nFileSize/0x100+1);
m_nRecv = 0;
case 'F':
sendto(m_socket, "R", 2, 0,
(SOCKADDR*)lParam, sizeof(SOCKADDR));
m_progress_r.StepIt();
m_nRecv++;
m_recv.Format("接收进度:(%.1f%%)", (float)m_nRecv/(nFileSize/0x100+1)*100);
UpdateData(false);
break;
case 'E':
m_progress_r.SetPos(nFileSize/0x100+1);
m_recv = "接收进度:(100%)";
UpdateData(false);
MessageBox("接收完毕!");
m_recv = "接收进度:";
m_progress_r.SetPos(0);
UpdateData(false);
break;
case 'C':
sendto(m_socket, "D", 2, 0,
(SOCKADDR*)lParam, sizeof(SOCKADDR));
break;
}
}
void CFilePosterDlg::OnMenuSend()
{
OnOK();
}
void CFilePosterDlg::OnMenuQuit()
{
OnCancel();
}
void CFilePosterDlg::OnAbout()
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
void CFilePosterDlg::OnMenuFind()
{
OnFindFile();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -