完成端口 WSASend问题...发送文件
以下是我做的其中一个函数,用来根据文件路径发送文件数据到客户端的。
先说问题:函数调用WSASend发送数据文件,像40多M的文件,函数只用了1秒都不到的时间(非阻塞的原因),这有可能吗?函数调用完后,只见客户端在不断的收啊收啊?所以这个我做的函数是不是有问题呢?客户端接收到的数据会不会出错呢?那我要怎么做发送文件的函数呢?
请大家帮我看看....
/***********************************************************
** 函数名称: BOOL CClientManager::sendFileToClient(CClientContext *pClient,CString &path)
** 功能描述: 发送文件到客户端
** 参 数: CClientContext *pClient 接受文件的客户端
CString &path 文件路径
** 返 回 值: 无
************************************************************/
BOOL CClientManager::sendFileToClient(CClientContext *pClient,CString &path)
{
DWORD dwStart = 0, dwStop = 0; //用来测试发送的文件所用的时间
dwStart = GetTickCount(); //开始发送的时间
HANDLE hFile=CreateFile(path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
if (hFile==INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
return FALSE;
}
DWORD dwFileSize=GetFileSize(hFile,0);
if (dwFileSize==0xFFFFFFFF)
{
return FALSE;
}
char* fileData = new char[Memory_Max]; //读取文件的缓存。大小是2048
u_int nReadIndex = 0;//当前读序号
pClient->AsyncSendPacket(MSG_Photo_RequestData,(char*)&nReadIndex,FILELEN);//发送文件第1部分。AsyncSendPacket这个是调用客户端WSASend发送的,格式是我定的
nReadIndex += 1;
DWORD nSendTimes = dwFileSize / ReadFilePartSize + 2; //+2是因为0和1我有其它用途 0:开始 1:结束
DWORD nlTotal = 0; //当前读取文件长度
DWORD nlRead; //每次读取文件长度
BOOL readOk = TRUE;
while (nlTotal != dwFileSize)//满足发送文件的长度,则退出循环
{
nReadIndex++; //读取次数加1
ZeroMemory(fileData,Memory_Max);
nlRead = 0;
memcpy(fileData,(char*)&nReadIndex,FILELEN);
if ( nReadIndex < nSendTimes )
{
if( ReadFile(hFile,fileData+FILELEN,ReadFilePartSize,&nlRead,NULL) == 0)
{
readOk = FALSE;
}
}else{
DWORD last = dwFileSize - nlTotal; //文件数据最后一次
if( ReadFile(hFile,fileData+FILELEN,last,&nlRead,NULL) == 0)
{
readOk = FALSE;
}
}
if(pClient->AsyncSendPacket(MSG_Photo_RequestData,fileData,(u_short)(nlRead+FILELEN)) == FALSE) //发送文件数据
{
break;
}
nlTotal += nlRead; //增加已读文件长度
}
CloseHandle(hFile);
delete []fileData;
dwStop = GetTickCount();
#ifdef _DEBUG
afxDump<<"BEGIN:"<<dwStart<<"\n";
afxDump<<"END:"<<dwStop<<"\n";
afxDump<<"USE:"<<dwStop - dwStart<<"\n";
#endif
return readOk;
}