안녕하세요 만해입니다.
지금 만드는 프로그램에서 쓰이는 루틴인데요
어떤 거냐면요
팁&트릭에 있는 임프님의 소스를 약간 고쳐서 만든
웹 페이지에 있는 그림 파일이나 미디어 파일 같은 그런 파일의
용량, 상태 코드, 파일의 종류를 받아 오는 루틴인데요
이게 딜레이가 너무 많이 걸리네요
좀더 빨리 할수 있는 방법이 없을까요?
아시는분 좀 알려 주세요
우선은 전체 소스를 올립니다.
TContent_Struct __fastcall TFrmSiteExplorer::GetObjData(AnsiString StrUrl)
{
TContent_Struct ObjData;
ObjData.AContent_Size = 0;
ObjData.AStatus_Code = 0;
ObjData.AContent_Type = "";
if ( StrUrl.AnsiPos("
http://") <= 0 )
StrUrl = "
http://" + StrUrl;
AnsiString Agent = "Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)";
HINTERNET ISession = InternetOpen(Agent.c_str() , INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
HINTERNET HttpFile = InternetOpenUrl(ISession, StrUrl.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
AnsiString UrlBuff;
UrlBuff.SetLength(1024);
DWord BuffSize = 1024;
AnsiString Status_Code;
Status_Code.SetLength(32);
// Content Status Code을 받아 내는 부분
if(HttpQueryInfo(HttpFile, HTTP_QUERY_STATUS_CODE, Status_Code.c_str(), &BuffSize, NULL)==false)
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
Status_Code.SetLength(Status_Code.Length()+1);
HttpQueryInfo(HttpFile, HTTP_QUERY_STATUS_CODE, Status_Code.c_str(), &BuffSize, 0);
break;
case ERROR_HTTP_HEADER_NOT_FOUND:
Status_Code = "";
break;
default:
InternetCloseHandle(HttpFile);
}
}
ObjData.AStatus_Code = Status_Code.ToIntDef(404);
if ( ObjData.AStatus_Code == 404 )
{
ObjData.AContent_Size = -1;
ObjData.AContent_Type = "Not Found";
return ObjData;
}
if(HttpQueryInfo(HttpFile, HTTP_QUERY_CONTENT_LOCATION, UrlBuff.c_str(), &BuffSize, NULL)==false)
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
UrlBuff.SetLength(BuffSize+1);
HttpQueryInfo(HttpFile, HTTP_QUERY_CONTENT_LOCATION, UrlBuff.c_str(), &BuffSize, 0);
break;
case ERROR_HTTP_HEADER_NOT_FOUND:
UrlBuff = StrUrl;
break;
default:
InternetCloseHandle(HttpFile);
}
}
char FileSizeBuff[4];
BuffSize = sizeof(FileSizeBuff);
// Content Size를 받아 내는 부분
bool bSizeIsKnown = HttpQueryInfo(HttpFile, HTTP_QUERY_CONTENT_LENGTH, &FileSizeBuff, &BuffSize, NULL);
bool Result;
DWord FileSize;
if(bSizeIsKnown)
{
FileSize = atol(FileSizeBuff);
ObjData.AContent_Size = FileSize;
}
else
{
char *Buffer = new char[2048];
FileSize = 2048;
unsigned long ByteRead;
unsigned long Count = 1000;
while(true)
{
Count--; //이 부분에서 무한 루프가 걸려서 일부러 카운터로 무한루프를 방지
Sleep(1);// 그런데 자주 무한 루프로 빠지네요 흑흑~
Application->ProcessMessages();
Result = InternetReadFile(HttpFile, Buffer, FileSize, &ByteRead);
ObjData.AContent_Size += ByteRead;
if ( ByteRead==0 )
break;
if ( Count == 0 )
{
ObjData.AContent_Size = -1;
break;
}
}
delete[] Buffer;
}
AnsiString Content_Type;
Content_Type.SetLength(32);
// Content Type을 받아 내는 부분
if(HttpQueryInfo(HttpFile, HTTP_QUERY_CONTENT_TYPE , Content_Type.c_str(), &BuffSize, NULL)==false)
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
Content_Type.SetLength(BuffSize+1);
HttpQueryInfo(HttpFile, HTTP_QUERY_CONTENT_TYPE, Content_Type.c_str(), &BuffSize, 0);
break;
case ERROR_HTTP_HEADER_NOT_FOUND:
UrlBuff = "";
break;
default:
InternetCloseHandle(HttpFile);
}
}
ObjData.AContent_Type.assign(Content_Type.c_str());
InternetCloseHandle(HttpFile);
InternetCloseHandle(ISession);
return ObjData;
}
여기까지가 소스 입니다.
이보다 좋은 소스나 혹은
소스 상의 오류가 있음 알려 주세요
부탁 드릴께요
이 소스를
데브피아에서 찾은
CInternetSession mysession("mysession");
mysession.SetCookie(m_szSessionURL, "JSESSIONID", (LPCTSTR)m_szSessionID );
CHttpFile *remotefile =
(CHttpFile*)mysession.OpenURL((LPCTSTR)m_szUrls,1,INTERNET_FLAG_TRANSFER_BINARY);
TCHAR szContentLength[100];
DWORD dwInfoSize = 32;
DWORD dwFileSize = 0;
// 이부분에서 서버로 리퀘스트를 한번 더 보내주시면 됩니다.
CString Header;
Header.Format("Range: bytes=0-\r\n");
remotefile->SendRequest(Header);
// 0바이트부터 받아오라는 메세지를 그냥 보냅니다-_-;
if (remotefile->QueryInfo( HTTP_QUERY_CONTENT_LENGTH, szContentLength, &dwInfoSize , NULL))
{
::MessageBox(NULL, szContentLength, "", MB_OK | MB_SETFOREGROUND);
}
else
{
::MessageBox(NULL, "Can't Query!", "", MB_OK | MB_SETFOREGROUND);
}
이 소스처럼 되어야 하는데
CHttpFile구조가 빌더에서 뭔지 모르겠네요
혹 아시는분 좀 갈켜 주세요~