由于发现InternetConnect和FtpPutFile会出现阻塞的情况,请大家看看我的代码
参看ms工程师解决wininet阻塞的方法,请大家看看有没有问题 我的网络情况很怪
HINTERNET g_hOpen, g_hConnect;
int FtpConnectThread(FServerAttrib* pConnA)
{
if ( !( g_hConnect = InternetConnect (
g_hOpen,
pConnA->raddr,
pConnA->rport,
pConnA->user,
pConnA->pwd,
INTERNET_SERVICE_FTP,
0,
0 ) ) )
{
DebugOutput(1,"InternetConnect 失败!%s\n",::GetLastError());
return 1; // failure
}
DebugOutput(1,"InternetConnect OK!\n");
return 0; // success
}
int FtpPutThread(PutAttrib* pPut)
{
// CString tmpp;
// tmpp = pPut->DataDir+CString("\\")+pPut->File;
// move a file by FTP
if(::FtpPutFile(g_hConnect,
pPut->DataDir+CString("\\")+pPut->File,
pPut->File,
INTERNET_FLAG_TRANSFER_ASCII,
0) )
{
DebugOutput(1,"文件<%s>上传成功\n",pPut->File.GetBuffer(100));
DeleteFile(pPut->File.GetBuffer(MAX_PATH));
}
else
{
DebugOutput(1,"文件<%s>上传失败,错误代码%d\n",
pPut->File.GetBuffer(100),::GetLastError());
//一旦错误全部不传避免顺序错误
return 1; //failure
}
return 0; //successs
}
//执行业务逻辑的函数
VOID WINAPI ServiceStart()
{
LPBYTE Result = new BYTE[MAX_PATH];
unsigned long n = MAX_PATH;
HKEY hk;
DWORD type=REG_SZ;
// if (::RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\\110FTPClient\\",&hk) != ERROR_SUCCESS)
if (::RegOpenKey(HKEY_LOCAL_MACHINE,REGCONTENT,&hk) != ERROR_SUCCESS)
return;
if(::RegQueryValueEx(hk,"IniDir",NULL,&type,Result,&n) != ERROR_SUCCESS)
return ;
printf("开始读取配置文件,初始化参数\n");
//配置文件位置,更新文件位置,全路径+文件名,远程ftp地址,用户,密码,远程的虚拟目录
CString IniPos,DataDir,temp,raddr,user,pwd,tt,VirDir;
//远程端口号,工作间隔时间,目录下的文件数量
int checktime,flag,servercount;
CIniFile CurInit(Result);
delete Result;
DataDir = CurInit.GetKeyValue(CString("local"),CString("DataDirectory"));
checktime = atoi(CurInit.GetKeyValue(CString("local"),CString("checktime")).GetBuffer(6));
Loglocation = CurInit.GetKeyValue(CString("local"),CString("LogDirectory"));
DebugLevel = atoi(CurInit.GetKeyValue(CString("local"),CString("Debugflag")).GetBuffer(6));
if(DebugLevel == 0)
intofile = false;
else
intofile = true;
servercount = atoi(CurInit.GetKeyValue(CString("local"),CString("remotecount")).GetBuffer(6));
FServerAttrib* pServer = new FServerAttrib[servercount];
for(int i = 0;i<servercount;i++)
{
char temp[10];
itoa(i+1,temp,10);
pServer[i].rname = CurInit.GetKeyValue(CString("remote")+CString(temp),CString("remotename"));
pServer[i].raddr = CurInit.GetKeyValue(CString("remote")+CString(temp),CString("remoteaddr"));
pServer[i].rport = atoi(CurInit.GetKeyValue(CString("remote")+CString(temp),CString("remoteport")).GetBuffer(7));
pServer[i].user = CurInit.GetKeyValue(CString("remote")+CString(temp),CString("user"));
pServer[i].pwd = CurInit.GetKeyValue(CString("remote")+CString(temp),CString("password"));
pServer[i].VirDir = CurInit.GetKeyValue(CString("remote")+CString(temp),CString("VirDir"));
}
//目录下的数据文件名数组
list<CString> Filename;
unsigned long ThreadID;
HANDLE hThread;
int dwTimeout = 15000;
while ( running )
{
Sleep(checktime);
DebugOutput(1,"到了固定间隔,开始工作\n");
for(int m = 0;m<servercount;m++) //检查每一个类型的文件,往不同的地方发
{
Filename.clear(); //将上次的文件名清空
//定时检查文件是否出现,出现的话上传,然后删除本地文件
flag = CheckNewFile(DataDir.GetBuffer(200),Filename,pServer[m].rname);
if ( flag <= 0)
{
DebugOutput(1," 没有找到文件,等待下次工作\n");
continue;
}
DebugOutput(1," 找到%d个类型%d文件\n",flag,m+1);
//依次将目录下面的文件上传
list<CString>::iterator iter;
if ( !( g_hOpen = InternetOpen ( "FTP Connect",
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
INTERNET_FLAG_ASYNC) ) )
{
DebugOutput(1,"InternetOpen发生错误:%d\n ",::GetLastError());
continue;
}
DebugOutput(2,"InternetOpen OK!\n ");
//开启InternetConn的线程,在这里控制它的退出,防止卡死
hThread = ::CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)FtpConnectThread,
(void*)&pServer[m],
0,
&ThreadID);
if (hThread == NULL)
DebugOutput(1,"开启InternetConn线程失败\n");
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
DebugOutput(1,"Ftp线程连接超时\n");
if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
DebugOutput(1,"InternetOpen已经关闭,等待线程结束\n");
//关闭internet handle让程序自己退出
WaitForSingleObject ( hThread, INFINITE );
::CloseHandle(hThread);
DebugOutput(1,"FtpConn线程因为阻塞结束\n");
continue;
}
// The state of the specified object (thread) is signaled
unsigned long dwExitCode = 0;
if ( !GetExitCodeThread( hThread, &dwExitCode ) )
{
DebugOutput(1,"GetExitCodeThread发生错误 \n" );
continue;
}
CloseHandle (hThread);
if ( dwExitCode ) //InternetConn失败
continue;
//InternetConn正常,开始传文件
//换到存放同步文件的虚拟目录
if(pServer[m].VirDir.GetLength() > 1)
{
DebugOutput(1,"切换到目录:%s\n",pServer[m].VirDir.GetBuffer(1));
::FtpSetCurrentDirectory(g_hConnect,pServer[m].VirDir);
}
else
{
DebugOutput(1,"没有设定ftp虚拟目录,直接放置在默认目录下\n");
}
DebugOutput(2,"开始逐个上传文件!\n ");
for (iter=Filename.begin();iter!=Filename.end();++iter)
{
//老办法,开启新的线程防治阻塞
PutAttrib pPutA;
pPutA.DataDir = DataDir;
pPutA.File = (*iter);
hThread = ::CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)FtpPutThread,
(void*)&pPutA,
0,
&ThreadID);
if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
{
DebugOutput(1,"Ftp线程发送超时\n");
// if ( g_hConnect )
// InternetCloseHandle( g_hConnect );
if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
DebugOutput(1,"InternetOpen&InternetConn已经关闭,FtpPut线程等待退出\n");
//不管了,让他在这里,我们下次再自己开线程干自己的
//WaitForSingleObject ( hThread, INFINITE );
//::TerminateThread(hThread,0);
::CloseHandle(hThread);
DebugOutput(1,"FtpPut线程阻塞,开启另外的线程开始工作\n");
continue;
}
// The state of the specified object (thread) is signaled
unsigned long dwExitCode = 0;
if ( !GetExitCodeThread( hThread, &dwExitCode ) )
{
DebugOutput(1,"GetExitCodeThread发生错误 \n" );
break;
}
CloseHandle (hThread);
if ( dwExitCode ) //InternetConn失败
break;
} //end of each file in one type
//关闭句柄
if ( g_hConnect )
InternetCloseHandle( g_hConnect );
if ( g_hOpen )
InternetCloseHandle( g_hOpen );
} //end of each type file
} //end of while running
}