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

📄 transfiledlg.cpp

📁 实现异步传输功能,有客户和服务器2个代码 有需要的可以参考
💻 CPP
字号:
// TransFileDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "TransFile.h"
#include "TransFileDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define WM_SOCKET			(WM_USER+1)
#define FILE_SUCESS			0
#define FILE_ACCEPT			1
#define FILE_FAILED			2

#define PORT				5150
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

	// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CTransFileDlg 对话框



CTransFileDlg::CTransFileDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTransFileDlg::IDD, pParent)
, m_sIP(_T(""))
, m_sFile(_T(""))
{
	m_sock=INVALID_SOCKET;
	m_bBlockMode=FALSE;
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTransFileDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDITIP, m_sIP);
	DDX_Text(pDX, IDC_EDITFILE, m_sFile);
	DDX_Control(pDX, IDC_PROGRESS, m_process);
	DDX_Control(pDX, IDC_SHOW, m_staticShow);
	DDX_Control(pDX, IDC_STATICFILEINFO, m_staticFInfo);
}

BEGIN_MESSAGE_MAP(CTransFileDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_CONNECT, OnBnClickedSend)
	ON_BN_CLICKED(IDC_BROWSE, OnBnClickedBrowse)
	ON_MESSAGE(WM_SOCKET, OnSocketEvent)
END_MESSAGE_MAP()


// CTransFileDlg 消息处理程序

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

	// 将\“关于...\”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	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);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	m_sIP="127.0.0.1";
	m_sFile="d:\\debug.rar";
	UpdateData(FALSE);
	m_process.SetRange(0,100);
	WSAAsyncSelect(m_sock,m_hWnd,WM_SOCKET,FD_CONNECT|FD_WRITE|FD_CLOSE);
	// TODO:在此添加额外的初始化代码

	return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
}

void CTransFileDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CTransFileDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作矩形中居中
		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;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CTransFileDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CTransFileDlg::OnBnClickedSend()
{
	GetDlgItem(IDC_CONNECT)->EnableWindow(FALSE);
	UpdateData(TRUE);

	m_hFile=CreateFile(m_sFile,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)NULL);
	if(m_hFile==INVALID_HANDLE_VALUE)
	{
		MessageBox("无法读取文件!");
		GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
		return ;
	}
	/*获取文件名*/
	char *pt=m_sFile.GetBuffer(_MAX_PATH);
	char *last=pt;
	while(*pt)
	{
		if(*pt=='\\')
			last=pt;
		pt++;
	}
	last++;
	/*填充文件信息*/
	strcpy(m_sFileInfo,last);
	DWORD dwLen=strlen(last);
	DWORD dwFileSize=::GetFileSize(m_hFile,0);
	*(DWORD *)(m_sFileInfo+dwLen+1)=dwFileSize;
	char sFileLen[50];
	sprintf(sFileLen,"文件长度:%d字节",dwFileSize);
	m_staticFInfo.SetWindowText(sFileLen);



	m_pFile=(char *)MapViewOfFile(m_hMap=CreateFileMapping(m_hFile,0,PAGE_READONLY|SEC_COMMIT,0,0,0),FILE_MAP_READ,0,0,0);

	if(m_sock==INVALID_SOCKET)
	{
		if((m_sock=socket(PF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
		{
			MessageBox("套接字创建失败!",0,0);
			return ;
		}
		WSAAsyncSelect(m_sock,m_hWnd,WM_SOCKET,FD_CONNECT|FD_WRITE|FD_READ|FD_CLOSE);
		sockaddr_in s;
		s.sin_addr.S_un.S_addr=inet_addr(m_sIP);
		s.sin_family=AF_INET;
		s.sin_port=htons(PORT);



		if(WSAConnect(m_sock,(sockaddr*) &s,sizeof(sockaddr),NULL,NULL,NULL,NULL)==SOCKET_ERROR)
		{
			int iError=WSAGetLastError();
			if(iError!=WSAEWOULDBLOCK)//如果是WSAEWOULDBLOCK说明过会才发送FD_CONNECT消息以判断是否成功
			{
				closesocket(m_sock);
				SetWindowText("连接失败!");
				GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
				return;
			}
		}
		else
			SetWindowText("连接成功");
	}
	else
	{
		PostMessage(WM_SOCKET,m_sock,FD_CONNECT);
		PostMessage(WM_SOCKET,m_sock,FD_WRITE);
	}
	m_iResult=FILE_FAILED;

	// TODO: 在此添加控件通知处理程序代码
}

void CTransFileDlg::OnBnClickedBrowse()
{
	CFileDialog fileDlg(TRUE);
	if(IDOK==fileDlg.DoModal())
	{
		SetDlgItemText(IDC_EDITFILE,fileDlg.m_ofn.lpstrFile);
	}
	// TODO: 在此添加控件通知处理程序代码
}

LRESULT CTransFileDlg::OnSocketEvent(WPARAM wParam,LPARAM lParam)//wParam好象是socket
{
	static char sSend[30];
	static DWORD dwSend,dwTotal,dwFlag;
	static	DWORD dwFileSize;


	int nErrorCode = WSAGETSELECTERROR(lParam);
	switch (WSAGETSELECTEVENT(lParam))
	{
	case FD_CONNECT:
		m_bOK=FALSE;
		if(!nErrorCode)
		{
			dwFileSize=*(DWORD *)(m_sFileInfo+strlen(m_sFileInfo)+1);
			SetWindowText("连接成功");
			m_buf[0].buf=m_sFileInfo;
			m_buf[0].len=_MAX_PATH+sizeof(DWORD);
			m_buf[1].buf=m_pFile;
			m_buf[1].len=dwFileSize;
			m_process.SetPos(0);
			m_staticShow.SetWindowText("0");

			dwSend=0;
			dwTotal=0;
		}
		else
		{
			closesocket(m_sock);
			m_sock=INVALID_SOCKET;

			switch(nErrorCode)
			{
			case WSAEADDRINUSE: 
				AfxMessageBox("The specified address is already in use.\n");
				break;
			case WSAEADDRNOTAVAIL: 
				AfxMessageBox("The specified address is not available from the local machine.\n");
				break;
			case WSAEAFNOSUPPORT: 
				AfxMessageBox("Addresses in the specified family cannot be used with this socket.\n");
				break;
			case WSAECONNREFUSED: 
				AfxMessageBox("The attempt to connect was forcefully rejected.\n");
				break;
			case WSAEDESTADDRREQ: 
				AfxMessageBox("A destination address is required.\n");
				break;
			case WSAEFAULT: 
				AfxMessageBox("The lpSockAddrLen argument is incorrect.\n");
				break;
			case WSAEINVAL: 
				AfxMessageBox("The socket is already bound to an address.\n");
				break;
			case WSAEISCONN: 
				AfxMessageBox("The socket is already connected.\n");
				break;
			case WSAEMFILE: 
				AfxMessageBox("No more file descriptors are available.\n");
				break;
			case WSAENETUNREACH: 
				AfxMessageBox("The network cannot be reached from this host at this time.\n");
				break;
			case WSAENOBUFS: 
				AfxMessageBox("No buffer space is available. The socket cannot be connected.\n");
				break;
			case WSAENOTCONN: 
				AfxMessageBox("The socket is not connected.\n");
				break;
			case WSAENOTSOCK: 
				AfxMessageBox("The descriptor is a file, not a socket.\n");
				break;
			case WSAETIMEDOUT: 
				AfxMessageBox("The attempt to connect timed out without establishing a connection. \n");
				break;
			default:
				TCHAR szError[256];
				wsprintf(szError, "OnConnect error: %d", nErrorCode);
				AfxMessageBox(szError);
				break;
			}
			GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
		}
		break;
	case FD_READ:
		WSABUF buf;
		buf.buf=(char *)&m_iResult;
		buf.len=sizeof(int);
		DWORD dwNum;
		if (WSARecv(m_sock, &buf, 1, &dwNum,&dwFlag, NULL, NULL) == SOCKET_ERROR)
		{
			if (WSAGetLastError() != WSAEWOULDBLOCK)
			{
				closesocket(m_sock);
				m_sock=INVALID_SOCKET;
				return 0;
			}
		}
		switch(m_iResult)
		{
		case FILE_ACCEPT:
			m_bOK=TRUE;
			break;
		case FILE_FAILED:
			m_bOK=FALSE;
			MessageBox("传送失败");
			GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
			m_process.SetPos(0);
			m_staticShow.SetWindowText("0");

			break;
		case FILE_SUCESS:
			MessageBox("传送完毕");
			GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
			break;
		}

		if(!m_buf[1].len || m_iResult==FILE_SUCESS )
		{
			m_process.SetPos(100);
			itoa(dwFileSize,sSend,10);
			m_staticShow.SetWindowText(sSend);

		}
		break;
	case FD_WRITE:
		static bFirst;
		if(WSASend(m_sock,m_buf,2,&dwSend,0,NULL,NULL) == SOCKET_ERROR)
		{
			static int iCount;
			int iError=WSAGetLastError();
			if(iError!= WSAEWOULDBLOCK && iError!=WSAENOBUFS && iError!=WSAEFAULT)
			{
				FailPrcess();
				closesocket(m_sock);
				m_sock=INVALID_SOCKET;

				
				GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
				MessageBox("发送失败");
				return 0;
			}
			if(iError==WSAENOBUFS)
			{
				m_bBlockMode=TRUE;
				m_buf[1].len=8192;
				PostMessage(WM_SOCKET,wParam,FD_WRITE);
				if(++iCount>5)
				{
					FailPrcess();
					iCount=0;
					GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
					MessageBox("发送失败");
				}
			}
			else
				iCount=0;
		}
		else
		{
			dwTotal+=dwSend;
			if(dwTotal<=_MAX_PATH+sizeof(DWORD))
			{
				m_buf[0].buf+=dwSend;
				m_buf[0].len-=dwSend;
			}
			else
			{
				DWORD dwRest=dwFileSize+_MAX_PATH+sizeof(DWORD)-dwTotal;
			
				m_buf[0].len=0;

				if(m_bBlockMode)//1
				{
					DWORD dwT=dwRest>=8192?8192:dwRest;
					m_buf[1].buf+=dwT;
					m_buf[1].len=dwT;
					if(dwT)
						PostMessage(WM_SOCKET,wParam,FD_WRITE);
				}//1
				else//1
				{
					int t=(dwTotal-dwSend<_MAX_PATH+sizeof(DWORD)?dwTotal-_MAX_PATH-sizeof(DWORD):dwSend);
					m_buf[1].buf+=t;
					m_buf[1].len-=t;
				}//1
				if(m_bOK)
				{
					m_process.SetPos(100-(int)((100.0*dwRest)/dwFileSize));
					itoa(dwFileSize-dwRest,sSend,10);
					m_staticShow.SetWindowText(sSend);
				}
				if(!m_buf[1].len)
				{
					FailPrcess();
					m_bBlockMode=FALSE;
				}
			}
		}
		break;
	case FD_CLOSE:
		closesocket(m_sock);

		if(nErrorCode==WSAECONNABORTED && m_iResult!=m_iResult)
		{
			MessageBox("发送请求被拒绝");
		}
		else
			MessageBox("服务端退出");
		m_sock=INVALID_SOCKET;
		GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);

		break;
	}
	return 0;

}


void CTransFileDlg::FailPrcess(void)
{
	UnmapViewOfFile(m_pFile);
	if(m_hFile!=INVALID_HANDLE_VALUE)
		CloseHandle(m_hFile);
	if(m_hMap!=INVALID_HANDLE_VALUE)
		CloseHandle(m_hMap);
	m_bOK=FALSE;
}

⌨️ 快捷键说明

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