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

📄 threadfunc.cpp

📁 实现文件传书是很有用的一个传书软件是大势的比口欧式
💻 CPP
字号:
// ThreadFunc.cpp : implementation file
//

#include "stdafx.h"
#include "FileTransferClient.h"
#include "ThreadFunc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//文件传输完成事件
HANDLE hEvent[NumOfThread];
//接收文件
char fn[40];
//接收数据套接字
CMySocket receiveSockets[NumOfThread];

// ThreadFunc

ThreadFunc::ThreadFunc()
{
}

ThreadFunc::~ThreadFunc()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(ThreadFunc, CAsyncSocket)
	//{{AFX_MSG_MAP(ThreadFunc)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// ThreadFunc member functions
//获得一个线程要写入文件的开始位和文件块大小
void GetBeginPos(int TotalThreads,int ThreadIndex,long file_length,long &BgPos,long &BlkSize)
{
	long BlockSize,lastBlockSize,BeginPos;
	//获取文件块平均大小
	BlockSize=file_length/TotalThreads;
	lastBlockSize=file_length;
	BeginPos=0;
	//获得第ThreadIndex块文件的开始位和大小
	for(int i=0;i<ThreadIndex-1;i++)
	{
		lastBlockSize=lastBlockSize-BlockSize;
		BeginPos+=BlockSize;
	}
	//如果是文件最后一块,取得最后一块大小
	if(ThreadIndex==TotalThreads)
	{
		BgPos=BeginPos;
		BlkSize=lastBlockSize;
	}
	else
	{
		BgPos=BeginPos;
		BlkSize=BlockSize;
	}
	return;
}

DWORD WINAPI ReceiveThreadFunction(void * pParam)
{
	int idx=(int)pParam;
	//调用接收函数
	ReceiveThread(idx+1);
	return 1;
}

void ReceiveThread(int idx)
{
	CFile file;
	char data[ReadSize];
	long BeginPos,Size;
	long FileLength;
	long WriteOnce;
	char filename[200];
	//命名临时文件名
	sprintf(filename,"tmpsave-%d.data",idx);
	if(!file.Open(filename,CFile::modeCreate|CFile::modeWrite))
	{
		AfxMessageBox("Write file error");
		return;
	}
	WaitForSingleObject(hMessageCome[idx-1],2000);
	while(SOCKET_ERROR==receiveSockets[idx-1].Receive(&FileLength,4))
	{
	}
	WaitForSingleObject(hMessageCome[idx-1],2000);
	while(SOCKET_ERROR==receiveSockets[idx-1].Receive(fn,40))
	{
	}
	//获取文件起始位和文件块大小
	GetBeginPos(NumOfThread,idx,FileLength,BeginPos,Size);
	//读取数据写入临时文件
	while(Size>0)
	{
		WaitForSingleObject(hMessageCome[idx-1],2000);
		//接收数据
		if(SOCKET_ERROR==(WriteOnce=receiveSockets[idx-1].Receive(data,ReadSize)))
		{
			ResetEvent(hMessageCome[idx-1]);
			continue;
		}
		Size=Size-WriteOnce;
		file.Write(data,WriteOnce);
	
	}
	//关闭文件
	file.Close();
	//设置文件发送完成事件对象,表示本线程文件块发送完成
	SetEvent(hEvent[idx-1]);
}

//监视线程
DWORD WINAPI MonitorFunc(void * pParam)
{
	//等待所有线程文件发送完成
	WaitForMultipleObjects(NumOfThread,hEvent,true,INFINITE);
	//调用合并临时文件块函数
	CombineFiles();
	AfxMessageBox("文件接收完成!!");
	return 1;
}

//合并临时文件块
void CombineFiles()
{
	CFile fileDest,fileSour;
	char sourname[500];
	static char data[10000];
	long count;
	//打开目的文件
	if(!fileDest.Open(fn,CFile::modeCreate|CFile::modeWrite))
	{
		AfxMessageBox("Combine:Make Dest File Error");
		return;
	}
	//读取临时文件并写入目的文件
	for(int i=0;i<NumOfThread;i++)
	{
		wsprintf(sourname,"tmpsave-%d.data",i+1);
		//打开临时文件
		if(!fileSour.Open(sourname,CFile::modeRead))
		{
			AfxMessageBox("Combine:Open Part File Error");
			return;
		}
		count=fileSour.Read(data,10000);
		//写入目的文件
		while(count>0)
		{
			fileDest.Write(data,count);
			count=fileSour.Read(data,10000);
		}
		fileSour.Close();
		//删除临时文件
		if(!DeleteFile(sourname))
		{
			AfxMessageBox("Comboine:File-Delete Error");
			return;
		}

	}
	fileDest.Close();
}

⌨️ 快捷键说明

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