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

📄 transfileserverdlg.cpp

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

#include "stdafx.h"
#include "TransFileServer.h"
#include "TransFileServerDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#pragma comment(lib,"ws2_32.lib")
#define WM_SOCKET			(WM_USER+100)
#define FILE_SUCESS			0
#define FILE_ACCEPT			1
#define FILE_FAILED			2

#define PORT				5150

// CTransFileServerDlg 对话框



CTransFileServerDlg::CTransFileServerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTransFileServerDlg::IDD, pParent)
, m_sDir(_T("")),m_iError(FILE_ACCEPT)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTransFileServerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PROGRESS, m_processCtrl);
	DDX_Control(pDX, IDC_SHOW, m_staticShow);
	DDX_Control(pDX, IDC_STATICFILEINFO, m_staticFInfo);
	DDX_Text(pDX, IDC_EDIT1, m_sDir);
}

BEGIN_MESSAGE_MAP(CTransFileServerDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_MESSAGE(WM_SOCKET, OnSocketEvent)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTONBROWSE, OnBnClickedButtonbrowse)
END_MESSAGE_MAP()


// CTransFileServerDlg 消息处理程序

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

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	if ((m_sockListen = WSASocket (AF_INET, SOCK_STREAM,IPPROTO_IP,0,0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
	{
		MessageBox("监听套接字创建失败!");
		return FALSE;
	} 
	WSAAsyncSelect(m_sockListen,m_hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE);//这里好象要创建一个线程
	sockaddr_in s;
	s.sin_family = AF_INET;
	s.sin_addr.s_addr = htonl(INADDR_ANY);
	s.sin_port = htons(PORT);

	m_processCtrl.SetRange(0,100);
	if (bind(m_sockListen, (PSOCKADDR) &s, sizeof(s)) == SOCKET_ERROR)
	{
		MessageBox("套接字绑定失败!");
		return FALSE;
	}

	if (listen(m_sockListen, 5))
	{
		MessageBox("listen函数失败");
		return FALSE;
	}



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

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

void CTransFileServerDlg::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 CTransFileServerDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
int CALLBACK FunCondition(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS,LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,GROUP FAR *g,DWORD dwCallbackData)
{
	sockaddr_in *ps=(sockaddr_in *)lpCallerId->buf;
	char *sIP=inet_ntoa(ps->sin_addr);
	char s[100];
	sprintf(s,"IP%s请求传送文件,是否接受?",sIP);
	if(MessageBox(theApp.m_pMainWnd->m_hWnd,s,0,MB_YESNO)==IDYES)
	{
		return CF_ACCEPT;
	}
	else
		return CF_REJECT;
}

LRESULT CTransFileServerDlg::OnSocketEvent(WPARAM wParam,LPARAM lParam)//wParam好象是socket
{
	static DWORD dwRecv,dwTotal;
	static HANDLE hFile,hMap;

	static SOCKET sockAccept;
	static DWORD dwFlag=0,dwFileSize;
	static char *lpFile,sRecv[50];
	static BOOL bOK=FALSE;

	switch(WSAGETSELECTEVENT(lParam))
	{
	case FD_ACCEPT:
		if ((sockAccept = WSAAccept(wParam,NULL,NULL,FunCondition,NULL)) == INVALID_SOCKET)
		{		
			MessageBox("工作套接字创建失败");
			break;
		}
		WSAAsyncSelect(sockAccept,m_hWnd, WM_SOCKET,FD_READ|FD_WRITE|FD_CLOSE);
		m_iError=FILE_ACCEPT;
		break;
	case FD_READ:

		if(!bOK)
		{
			m_buf[0].buf=m_sFileInfo;
			m_buf[0].len=_MAX_PATH+sizeof(DWORD);
			m_buf[1].buf=NULL;
			m_buf[1].len=0;
			dwTotal=0;
			m_iError=FILE_ACCEPT;
			m_processCtrl.SetPos(0);
			m_staticFInfo.SetWindowText("");
			m_staticShow.SetWindowText("0");

			UpdateData(TRUE);
			SendMessage(WM_SOCKET,wParam,FD_WRITE);
			m_iError=-1;
			bOK=TRUE;
		}
	if(WSARecv(sockAccept,m_buf,2,&dwRecv,&dwFlag,NULL,NULL)==SOCKET_ERROR)//接收时,实际上是装满一个再装另一个,并非跟客户端是一一对应的
		{
			int iErrorCode=WSAGetLastError();
			if (iErrorCode!= WSAEWOULDBLOCK  && iErrorCode!=WSAEFAULT)
			{
				UnmapViewOfFile(lpFile);
				CloseHandle(hMap);
				CloseHandle(hFile);
				closesocket(sockAccept);

				bOK=FALSE;
				MessageBox("接收文件时发生错误");
				m_iError=FILE_FAILED;
				SendMessage(WM_SOCKET,wParam,FD_WRITE);
				m_iError=-1;
				return 0;
			}
		}
		else
		{
			dwTotal+=dwRecv;
			if(dwTotal<=_MAX_PATH+sizeof(DWORD))//1
			{
				m_buf[0].buf+=dwRecv;
				m_buf[0].len-=dwRecv;
				if(dwTotal==_MAX_PATH+sizeof(DWORD))//2
				{
					dwFileSize=m_buf[1].len=*((unsigned long *)(m_sFileInfo+strlen(m_sFileInfo)+1));				
					sprintf(sRecv,"文件名:%s,文件长度:%d字节",m_sFileInfo,dwFileSize);
					m_staticFInfo.SetWindowText(sRecv);
					int len=m_sDir.GetLength();

					if(len)
					{
						if(m_sDir.GetAt(len-1)!='\\') 
							m_sDir+=(CString("\\")+m_sFileInfo);
						else
							m_sDir+=m_sFileInfo;
					}
					else
						m_sDir=m_sFileInfo;


					hFile=CreateFile(m_sDir,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,(HANDLE)NULL);
					if(dwFileSize==0)
					{
						CloseHandle(hFile);
						bOK=FALSE;
						m_processCtrl.SetPos(100);
						MessageBox("接收完毕!");

						m_iError=FILE_SUCESS;
						SendMessage(WM_SOCKET,wParam,FD_WRITE);
						m_iError=-1;

					}

					lpFile=(char *)MapViewOfFile(hMap=CreateFileMapping(hFile,0,PAGE_READWRITE,0,dwFileSize,0),FILE_MAP_WRITE,0,0,0);
					if(hFile==INVALID_HANDLE_VALUE || (!lpFile && dwFileSize))
					{
						m_iError=FILE_FAILED;
						PostMessage(WM_SOCKET,wParam,FD_WRITE);
					}
					m_buf[1].buf=lpFile;
				}//2


			}//1
			else
			{
				m_buf[1].buf+=dwRecv;
				m_buf[1].len-=dwRecv;
				itoa(dwFileSize-m_buf[1].len,sRecv,10);
				int iPos=100-(int)((100.0*m_buf[1].len)/dwFileSize);
				m_processCtrl.SetPos(iPos);
				m_staticShow.SetWindowText(sRecv);
				if(!m_buf[1].len && dwRecv)
				{
					UnmapViewOfFile(lpFile);
					CloseHandle(hMap);
					CloseHandle(hFile);
					bOK=FALSE;
					MessageBox("接收完毕!");
					m_iError=FILE_SUCESS;
					PostMessage(WM_SOCKET,wParam,FD_WRITE);
				}
			}
		}
		break;
	case FD_WRITE:
		if(m_iError==-1)
			return 0;
		WSABUF buf;
		buf.buf=(char *)&m_iError;
		buf.len=sizeof(DWORD);
		DWORD dwWrite;
		if(WSASend(sockAccept,&buf,1,&dwWrite,0,NULL,NULL) == SOCKET_ERROR)
		{
			if(WSAGetLastError() != WSAEWOULDBLOCK)
			{
				closesocket(sockAccept);
				return 0;
			}
		}
		break;
	case FD_CLOSE:
		closesocket(sockAccept);
		MessageBox("客户端程序退出或套接字错误");
		break;
	}

	return 0;
}

void CTransFileServerDlg::OnBnClickedButtonbrowse()
{
	BROWSEINFO bi;
	bi.hwndOwner=GetSafeHwnd();
	bi.pidlRoot=0;
	bi.pszDisplayName=0;
	bi.lpszTitle="选择目录";
	bi.lpfn=0;
	bi.lParam=0;
#define BIF_USENEWUI 0X0040 
	bi.ulFlags= BIF_STATUSTEXT | BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
	LPITEMIDLIST pidl ;
	if (pidl = SHBrowseForFolder(&bi))
	{  
		SHGetPathFromIDList(pidl, m_sDir.GetBufferSetLength(_MAX_PATH));
		UpdateData(FALSE);
	}
}

⌨️ 快捷键说明

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