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

📄 carryfile.cpp

📁 基于TCP的局域网多用户通信、文件传送程序详解
💻 CPP
字号:
// CarryFile.cpp : implementation file
//

#include "stdafx.h"
#include "wbqqclient.h"
#include "CarryFile.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////发送线程///////////////////////////////////////////////////
UINT dlgSend(void *d)
{
	CCarryFile *pDlg = (CCarryFile*)d;
	int status;
	SOCKET destSocket;
	SOCKADDR_IN sockAddr;
	int len = sizeof (sockAddr);
	memset(&sockAddr, 0, sizeof (sockAddr));
	sockAddr.sin_port = htons(1999);
	sockAddr.sin_family = AF_INET;
	sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	destSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (destSocket == INVALID_SOCKET)
	{
		AfxMessageBox("socket unsuccsessful!", MB_OK);
		return false;
	}
	status = bind(destSocket, (LPSOCKADDR)&sockAddr, sizeof (sockAddr));
	if (status == SOCKET_ERROR)
	{
		AfxMessageBox("ERROR: bind unsuccsessful!" + GetLastError(), MB_OK);
		return false;
	}
	status = listen(destSocket, 1);
	if (status == SOCKET_ERROR)
	{
		AfxMessageBox("ERROR: listen unsuccsessful!", MB_OK);
		return false;
	}
	SOCKET sendSocket;
	sendSocket = accept(destSocket, (LPSOCKADDR)&sockAddr, &len);
	closesocket(destSocket);	//关闭原来的套接字
	pDlg->GetDlgItem(IDCANCEL)->EnableWindow(false);
	pDlg->m_ctrState.SetWindowText("请选择要发送的文件");
	CFileDialog dlg(true);
	dlg.m_ofn.lpstrTitle = pDlg->m_strCaption.GetBuffer(40);//设置打开文件对话框标题栏
	if (dlg.DoModal() == IDOK)
	{
		CString strFileName = dlg.GetPathName();
		CFile file;
		file.Open(strFileName, CFile::modeRead | CFile::typeBinary);
		pDlg->m_ctrFileName.SetWindowText(file.GetFileName());
		pDlg->m_ctrFilePath.SetWindowText(file.GetFilePath());
		long lFileSize = file.GetLength();
		pDlg->m_nUpper = (int)lFileSize;	//用于传输速度控制
		pDlg->m_progress.SetRange32(0, lFileSize);	//设置进度条范围
		pDlg->m_progress.SetStep(1);	//设置进度条步长
		char temp[1024];	//首先用来存放文件大小,后面用作发送文件缓冲区
		ltoa(lFileSize, temp, 10);
		pDlg->m_ctrFileSize.SetWindowText(temp);
		pDlg->m_progress.ShowWindow(SW_SHOW);
		CString str;
		str = strFileName;
		str += "*";
		str += temp;
		send(sendSocket, str, str.GetLength(), 0);	//发送文件的名称和大小
/////////////////////////发送文件///////////////////////////////////////////
		int end = 0;
		long tmp = 0;
		char cent[15];
		pDlg->m_ctrState.SetWindowText("正在发送文件");
		while (1)
		{
			len = file.Read(temp, 1024);
			if (len == 0)
			{
				break;
			}
			end = send(sendSocket, temp, sizeof(temp), 0);
			if (end == SOCKET_ERROR)
			{
				AfxMessageBox("发送线程UINT dlgSend(void *d)出错!");
				break;
			}
			tmp += end;
			pDlg->m_progress.SetPos(tmp);
			strcpy(cent, ltoa(((tmp * 100) / lFileSize), cent, 10));
			strcat(cent, "%");
			pDlg->m_ctrCent.SetWindowText(cent);
		}
		file.Close();
/////////////////判断发送是否成功、结束处理////////////////////////////////////
		if (tmp == lFileSize)
		{
			AfxMessageBox("文件发送成功!");
		}
		else
		{
			AfxMessageBox("文件发送失败!");
		}
		pDlg->m_progress.ShowWindow(SW_HIDE);
		cent[0] = '\0';
		pDlg->m_ctrCent.SetWindowText(cent);
		pDlg->m_ctrSpeed.SetWindowText("0");
		pDlg->m_ctrState.SetWindowText("发送文件结束");
	}
	pDlg->GetDlgItem(IDCANCEL)->SetWindowText("关闭");
	pDlg->GetDlgItem(IDCANCEL)->EnableWindow(true);
	shutdown(destSocket, 2);
	if (0 != closesocket(sendSocket))
	{
		AfxMessageBox("dlgSend:closesocket(sendSocket)失败!");
	}
//	pDlg->DestroyWindow();	//销毁传送文件对话框

	ExitThread(0);
	return 0;
}
/////////////////////////////////////////////////////////////////////////////
//////////////////接收线程///////////////////////////////////////////////////
UINT dlgRecv(void *d)
{
	CCarryFile *pDlg = (CCarryFile*)d;
	int status;
	SOCKET destSocket;
	SOCKADDR_IN sockAddr;
	u_long destAddr = inet_addr(pDlg->m_destIP);
	memcpy(&sockAddr.sin_addr, &destAddr, sizeof (destAddr));
	sockAddr.sin_port = htons(1999);
	sockAddr.sin_family = AF_INET;
	destSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (destSocket == INVALID_SOCKET)
	{
		AfxMessageBox("ERROR:socket unsccessful!", MB_OK);
		ExitThread(0);
	}
/////////////////////用套接字连接服务器//////////////////////////////////////////
	status = connect(destSocket, (LPSOCKADDR)&sockAddr, sizeof(sockAddr));
	if (status == SOCKET_ERROR)
	{
		AfxMessageBox("ERROR:connect unsccessful!", MB_OK);
		status = closesocket(destSocket);
		if (status == SOCKET_ERROR)
		{
			AfxMessageBox("ERROR:closesocket unsccessful!", MB_OK);
		}
	}
	char buffer[1024] = {0};
	char temp[1024] = {0};
	int rcv = recv(destSocket, buffer, 1024, 0);
	for (int i=0; buffer[i]!='*'; i++)
	{
		temp[i] = buffer[i];
	}
	temp[i++] = '\0';
	CString strFileName = temp;
	strcpy(temp, buffer + i);
	long lFileSize = atol(temp);
	pDlg->m_ctrState.SetWindowText("请选择保存路径和文件名");
	CFileDialog dlg(false);
	strcpy(buffer, pDlg->m_strCaption);
	strcat(buffer, "\t文件大小:");
	strcat(buffer, temp);
	strcat(buffer, "b");
	dlg.m_ofn.lpstrTitle = buffer;	//设置保存文件对话框标题栏
	dlg.m_ofn.lpstrFile = strFileName.GetBuffer(1024);
	if (dlg.DoModal() == IDOK)
	{
		pDlg->GetDlgItem(IDCANCEL)->EnableWindow(false);
		CString fName;
		fName = dlg.GetPathName();
		pDlg->m_ctrFilePath.SetWindowText(fName);	//得到保存文件的路径和名称
		pDlg->m_ctrFileName.SetWindowText(dlg.GetFileName());
		pDlg->m_ctrFileSize.SetWindowText(temp);
		pDlg->m_nUpper = (int)lFileSize;	//用于传输速度控制
		pDlg->m_progress.SetRange32(0, lFileSize);	//设置进度条范围
		pDlg->m_progress.SetStep(1);	//设置进度条步长
		pDlg->m_progress.ShowWindow(SW_SHOW);
///////////接收并保存文件////////////////////////////////////////////////////
		CFile file(fName, CFile::modeCreate | CFile::modeWrite);
		long temp = 0;
		char cent[15];
		pDlg->m_ctrState.SetWindowText("正在接收文件");
		while (1)
		{
			rcv = recv(destSocket, buffer, 1024, 0);
			if (rcv == 0)
			{
				break;
			}
			file.Write(buffer, rcv);
			temp += rcv;
			pDlg->m_progress.SetPos(temp);
			strcpy(cent, ltoa(((temp * 100) / lFileSize), cent, 10));
			strcat(cent, "%");
			pDlg->m_ctrCent.SetWindowText(cent);
		}
		file.Close();
		if (temp == lFileSize)
		{
			AfxMessageBox("文件接收成功!");
		}
		else
		{
			AfxMessageBox("文件接收失败!");
		}
		pDlg->m_ctrSpeed.SetWindowText("0");
		pDlg->m_progress.ShowWindow(SW_HIDE);
		cent[0] = '\0';
		pDlg->m_ctrCent.SetWindowText(cent);
		pDlg->m_ctrState.SetWindowText("接收文件结束");
	}
	pDlg->GetDlgItem(IDCANCEL)->SetWindowText("关闭");
	pDlg->GetDlgItem(IDCANCEL)->EnableWindow(true);
	shutdown(destSocket, 2);
	if (0 != closesocket(destSocket))
	{
		AfxMessageBox("dlgRecv:closesocket(destSocket)失败!");
	}
//	pDlg->DestroyWindow();	//销毁传送文件对话框

	ExitThread(0);
	return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CCarryFile dialog


CCarryFile::CCarryFile(CWnd* pParent /*=NULL*/)
	: CDialog(CCarryFile::IDD, pParent)
{
	//{{AFX_DATA_INIT(CCarryFile)
	m_strState = _T("");
	//}}AFX_DATA_INIT
	m_bSendFile = false;
	m_pThread = NULL;
	m_nSpeed = 0;
	m_nUpper = 0;
}


void CCarryFile::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CCarryFile)
	DDX_Control(pDX, IDC_STATIC_SPEED, m_ctrSpeed);
	DDX_Control(pDX, IDC_PERCENT, m_ctrCent);
	DDX_Control(pDX, IDC_EDIT_FILEPATH, m_ctrFilePath);
	DDX_Control(pDX, IDC_EDIT_FILENAME, m_ctrFileName);
	DDX_Control(pDX, IDC_EDIT_STATE, m_ctrState);
	DDX_Control(pDX, IDC_STATIC_FILESIZE, m_ctrFileSize);
	DDX_Control(pDX, IDC_PROGRESS, m_progress);
	DDX_Text(pDX, IDC_EDIT_STATE, m_strState);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CCarryFile, CDialog)
	//{{AFX_MSG_MAP(CCarryFile)
	ON_WM_DESTROY()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCarryFile message handlers

BOOL CCarryFile::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	SetWindowText(m_strCaption);	//设定对话框标题
	GetDlgItem(IDC_PROGRESS)->ShowWindow(SW_HIDE);	//隐藏进度条
	if (m_bSendFile)
	{
		m_strState = "等待对方回应";
		m_pThread = AfxBeginThread(dlgSend, this);
	}
	else
	{
		m_strState = "等待对方发送文件";
		m_pThread = AfxBeginThread(dlgRecv, this);
	}
	UpdateData(false);
	SetTimer(1, 500, NULL);	//控制传输速度显示,半秒更新一次
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CCarryFile::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	if (WAIT_OBJECT_0 != WaitForSingleObject(m_pThread, 0))
	{
		TerminateThread(m_pThread, 0);
	}
}

void CCarryFile::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if (nIDEvent == 1)
	{
		int temp = m_nSpeed;
		m_nSpeed = m_progress.GetPos();
		int nVal = (m_nSpeed - temp) * 2;
		CString str;
		str.Format("%d", nVal);
		m_ctrSpeed.SetWindowText(str);
		if (m_nSpeed = m_nUpper)
		{
			KillTimer(nIDEvent);
		}
	}
	
	CDialog::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

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