Download (скачивание) c HTPP-сервера с помощью MFC

Эта проблема решается с помощью bsd-styled сокетов, компиляция в Visual C++. Просто нужно было, чтобы экзешник получился маленьким :)

char *RbcMessage[] =
{
"GET https://www.rbc.ru/out/801.csv HTTP/1.0\r\n",
"Accept: */*\r\n",
"Referer: https://www.rbc.ru\r\n",
"Accept-Language: ru\r\n",
"Accept-Encoding: gzip, deflate\r\n",
"User-Agent: Informer from RBC\r\n",
"Host: www.rbc.ru\r\n\r\n\r\n",
NULL
};

SOCKADDR_IN remoteAddr;
PHOSTENT phe;
SOCKET SendSocket;
CString m_Kurs;
CString m_Line;

int err;
int iMsg = 0;
int iLength;
int iEnd = 0;
int ndx;
int bytesReceived = 0;
char szLine[712]; //предполагаемая длина принимаемого файла
iLength = 0;

WSADATA WSAData;
WSAStartup(MAKEWORD(1, 1), &WSAData);

//создаём сокет
struct sockaddr_in srv_address;
int namelen;

SendSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(SendSocket != INVALID_SOCKET) {
memset(&srv_address,0,sizeof(SOCKADDR_IN));
srv_address.sin_addr.S_un.S_addr=INADDR_ANY;
srv_address.sin_family = AF_INET;
srv_address.sin_port = 0;
}
if(bind(SendSocket, (SOCKADDR *) &srv_address, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) {
closesocket(SendSocket);
return FALSE;
} else {
namelen=sizeof(SOCKADDR_IN);
getsockname(SendSocket,(SOCKADDR *)&srv_address,&namelen);
return TRUE;
}

//соединяем сокет с сервером
if((phe = gethostbyname("www.rbc.ru"))!=0){ remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons(RBC_PORT);
memcpy((char *)&(remoteAddr.sin_addr), phe->h_addr, phe->h_length);

err = connect (SendSocket, (PSOCKADDR) & remoteAddr, sizeof (remoteAddr));
if(err) {
m_Kurs = "Невозможно соединиться с сервером";
return FALSE;
}
else {
do {
send(SendSocket, (LPSTR)RbcMessage[iMsg], strlen(RbcMessage[iMsg]), 0);
iMsg++;
} while(RbcMessage[iMsg]);
}

do {
iLength = recv(SendSocket, szLine, 712, 0);
if(iLength) {
// Здесь проводится разборка принимаемого файла
m_Line = szLine;
if((ndx = m_Line.Find("USD ЦБ РФ"))!=-1) {
m_Line = m_Line.Left(ndx+23);
m_Line = m_Line.Mid(ndx+10);
m_Kurs = "Курс ЦБ РФ: ";
m_Kurs += m_Line;
}
else m_Kurs = "Неудаётся получить файл с сервера";
}
if(iLength==0) break;
bytesReceived += iLength;
} while ( bytesReceived < 712 );
}
else {
m_Kurs = "Неудаётся установить связь с сервером";
return FALSE;
}
Естевственно надо не забыть добавить в проект файл WSOCK32.LIB OlegO опубликован 06-03-2001 13:11 MSK Закачку файла не так сложно организовать используя MFC класы, или библиотеки WinInet. в первом случае посмотри CInternetSession, CHttpConnection, CHttpFile пример для наглядности:
try
{
CString lpstrProxy=strProxyName+":"+strProxyPort;
CInternetSession mysession(NULL,0,AccessType,lpstrProxy,NULL);

CHttpFile *remotefile = (CHttpFile *)mysession.OpenURL(strUrl,1,INTERNET_FLAG_TRANSFER_BINARY);
if (remotefile==NULL)
{
AfxMessageBox("Can't find file on the server...", MB_OK|MB_ICONSTOP);
}

CFile myfile(SavePath, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);

int numbytes = 0;
long HTTPBUFLEN = 1000L;

TCHAR httpsbuff[HTTPBUFLEN];

while (numbytes = remotefile->Read(httpsbuff, HTTPBUFLEN))
{
myfile.Write(httpsbuff, numbytes);

}
myfile.Close ();
remotefile->Close ();
delete remotefile;
}
catch(CException* e)
{
e->Delete();
}

... для второго метода ф-и дублируют классы, они находятся wininet.h wininet.lib, но используют больше возможностей настройки
 
« Предыдущая статья   Следующая статья »