根据连接数量,将文件均分后存储到所连接的主机上去。使用了完成端口
CStoreClientDlg检测到FD_ACCEPT后,投递一个接收请求。
线程函数是:
DWORD WINAPI ServerThread(LPVOID lpParam)
{
// 得到完成端口对象句柄
CStoreClientDlg *pdlg=(CStoreClientDlg*)lpParam;
HANDLE hCompletion = pdlg->hCompletion ;
DWORD dwTrans=0;
PPER_HANDLE_DATA pPerHandle=new PER_HANDLE_DATA;
PPER_IO_DATA pPerIO=NULL;
while(TRUE)
{
    // 在关联到此完成端口的所有套接字上等待I/O完成
    BOOL bOK = ::GetQueuedCompletionStatus(hCompletion, 
&dwTrans, (LPDWORD)&pPerHandle, (LPOVERLAPPED*)&pPerIO, WSA_INFINITE);
    if(!bOK) // 在此套节字上有错误发生
    {
if(pPerHandle->s) ::closesocket(pPerHandle->s);
if(pPerHandle) ::GlobalFree(pPerHandle);
if(pPerIO) ::GlobalFree(pPerIO);
continue;
    }

    if(dwTrans == 0 && // 套节字被对方关闭
(pPerIO->noptype != OP_WRITE ))
    {
if(pPerHandle->s) ::closesocket(pPerHandle->s);
if(pPerHandle) ::GlobalFree(pPerHandle);
if(pPerIO) ::GlobalFree(pPerIO);
continue;
    }
    switch(pPerIO->noptype )
    {
    case OP_WRITE:
event.Lock ();
if(bStart)
{
if(pdlg->mpsi ->filename .IsEmpty ()) continue;
WaitForSingleObject(g_hMutex,INFINITE);//互斥访问全局变量nNextPart.
CString strfile,str;
if(pdlg->mpsi ->bparted ) 
{
strfile.Format ("%s-%d",pdlg->mpsi ->filename ,nNextPart );
str.Format ("\\%s-%d\\",pdlg->mfilename ,nNextPart );
nNextPart++;
}
else 
{
str.Format ("\\%s\\",pdlg->mfilename );
strfile=pdlg->mfullname ;
}
                            //先发送文件名
if(SOCKET_ERROR==send(pPerHandle->s ,str,str.GetLength (),0))
{
int nerr=WSAGetLastError();
CString strerr;
strerr.Format ("Error code=%d",nerr);
::MessageBox (::AfxGetMainWnd ()->m_hWnd ,strerr,"tips",MB_OK);
}
::MessageBox (::AfxGetMainWnd ()->m_hWnd ,strfile,"tips",MB_OK);
ReleaseMutex(g_hMutex);
HANDLE  hfile=::CreateFile(strfile ,GENERIC_READ,//打开文件
FILE_SHARE_READ,NULL,OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,NULL);

BOOL bRet=FALSE;

if(hfile!=INVALID_HANDLE_VALUE)
{
::MessageBox(::AfxGetMainWnd ()->m_hWnd,"准备发送文件!","提示",MB_OK);
///修改
pPerIO->noptype =OP_READ;
memset(&pPerIO->ol ,0,sizeof(OVERLAPPED));
*reinterpret_cast<HANDLE*>(pPerIO->buf)=hfile;//发送文件
bRet=TransmitFile(pPerHandle->s ,hfile,GetFileSize(hfile,NULL),
4096,reinterpret_cast<LPOVERLAPPED>(pPerIO),NULL,
TF_DISCONNECT );
}
else
::MessageBox(::AfxGetMainWnd ()->m_hWnd,"文件有误!","提示",MB_OK);
::MessageBox(::AfxGetMainWnd ()->m_hWnd,"发送完毕!","提示",MB_OK);
}
//break;
}
}
return 0;
}3台主机测试结果:A将文件分成2部分后,只能有1部分发送出去,而另一部分未发送,
明明投递了2次接收请求,但上述线程只有1个执行了。
期待的结果是2部分分别发送到B和C上去。请问这个线程函数问题在哪里?
谢谢大家了。困扰了好久了。也期待简单合理的方法和代码。