Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.116.40.53] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Здравствуйте, хочу узнать размер файла расположенного на интернет сервере (сайте). Полазил по форуму много топиков, но ошибку так и не могу исправить (может запрос GET не так формирую может ещё чего), пишу на WinAPI + WinSocks. Нужно получить ответ от сервера, хочу распечатать его... Чтобы потом отпарсить и узнать размер. Пожалуйста помогите по возможности
П.С.: при компилировании безобидного кода антивирус говорил мол вирус, как его от этого отучить (программно)? Скрытый текст #include <stdafx.h> #include <stdio.h> #include <stdlib.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib, "ws2_32.lib") int main(int argc, char *argv[]) { WSADATA wsa; SOCKET s; struct sockaddr_in addr; printf("\r\n Socket template\r\n\r\n"); printf(" Initializing winsock...\t"); if(WSAStartup(MAKEWORD(1,1),&wsa)!=0) { printf("NO\r\n"); exit(0); } printf("OK\r\n"); printf(" Creating socket...\t"); if((s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) { printf("NO\r\n"); WSACleanup(); exit(0); } printf("OK\r\n"); addr.sin_family=AF_INET; addr.sin_port=htons(80); addr.sin_addr.s_addr=inet_addr("127.0.0.1"); printf(" Connecting to main server...\t"); if(connect(s, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR) { printf("NO\r\n"); closesocket(s); WSACleanup(); exit(0); } printf("OK\r\n"); ////////////////////////////////////////////////////////////////////////////// char *buf=(char *)malloc(1024*1024); strcpy(buf, "GET /download/kingdia-video-converter.exe HTTP/1.0\r\n"); strcat(buf, "Host: http://www.kingdia.com\r\n"); strcat(buf, "HTTP-Agent: Socket template\r\n"); strcat(buf, "Connection: Close\r\n\r\n"); printf(" Sending information...\t"); if(send(s, buf, strlen(buf), 0)==SOCKET_ERROR) { printf("NO\r\n"); closesocket(s); WSACleanup(); exit(0); } printf("OK\r\n"); printf(" Reading neccessary bytes...\t"); memset(buf, 0x00, sizeof(buf)); int count=0, check=-1; while(check!=0) { check=recv(s, buf, 1024*1024, 0); count+=check; } printf("OK [%i bytes]\r\n", count); closesocket(s); WSACleanup(); system("PAUSE"); return 0; } |
Сообщ.
#2
,
|
|
|
M Тема перенесена из C/C++ -> C/C++: Системное программирование и WinAPI |
Сообщ.
#3
,
|
|
|
не многовато ли?) + не удаляешь buf;
char *buf=(char *)malloc(1024*1024); не правильно так делать, если сервер оборвет соединение после твоего запроса, то recv вернет -1 while(check!=0) { check=recv(s, buf, 1024*1024, 0); count+=check; } |
Сообщ.
#4
,
|
|
|
Цитата popsa @ не многовато ли?) + не удаляешь buf; char *buf=(char *)malloc(1024*1024); Освобождение добавлю free(buf); Оставлю 4096 char *buf=(char *)malloc(4096); Цитата popsa @ не правильно так делать, если сервер оборвет соединение после твоего запроса, то recv вернет -1 while(check!=0) { check=recv(s, buf, 1024*1024, 0); count+=check; } А как сдесь нужно сделать? |
Сообщ.
#5
,
|
|
|
Romeo
Зачем делать трудности если, можно получить информацию о размере файла с помошью запроса HEAD Вот написал на сокетах + парсер написал как раз чтоб отискал строку Content-Length #include <windows.h> WSADATA wsa_data; SOCKET s; sockaddr_in addr; hostent* hn; int len, a, b, c; char serverName[512],serverParam[512]; char serget[1280]; char BufLoad[1492]; char buferOut[100]; void Run(); void Run() { Beep(500,100); lstrcpy(serverName,"www.kingdia.com"); lstrcpy(serverParam,"download/kingdia-video-converter.exe"); lstrcpy(serget,"HEAD /"); // Формирование запроса HEAD lstrcat(serget,serverParam); lstrcat(serget," HTTP/1.0\r\nHost: "); lstrcat(serget,serverName); lstrcat(serget,"\r\nUser-Agent: TRANSFORMER\r\nAccept: text/html\r\nConnection: close\r\n\r\n"); WSAStartup(0x0202,&wsa_data); s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); hn=gethostbyname(serverName); addr.sin_family=AF_INET; addr.sin_port=htons(80); addr.sin_addr.S_un.S_addr=*(DWORD*)hn->h_addr_list[0]; connect(s,(LPSOCKADDR)&addr,sizeof(addr)); send(s,serget,lstrlen(serget),0); RtlZeroMemory(BufLoad,1492); recv(s,BufLoad,1492,0); // Запрос у нас маленький так что не стоит recv ставить в цикл так как мы не собираемся получать весь файл а всего лишь запрашиваем размер у сервера closesocket(s); WSACleanup(); MessageBox(NULL,BufLoad,"Ответ от сервера",32); // Парсер a=0; b=0; c=0; len=lstrlen(BufLoad); for (a=0;a<len;a++) { if ((BufLoad[a]=='C')&& (BufLoad[a+1]=='o')&& (BufLoad[a+2]=='n')&& (BufLoad[a+3]=='t')&& (BufLoad[a+4]=='e')&& (BufLoad[a+5]=='n')&& (BufLoad[a+6]=='t')&& (BufLoad[a+7]=='-')&& (BufLoad[a+8]=='L')&& (BufLoad[a+9]=='e')&& (BufLoad[a+10]=='n')&& (BufLoad[a+11]=='g')&& (BufLoad[a+12]=='t')&& (BufLoad[a+13]=='h')) { for (b=(a+15);b<len;b++) { if ((BufLoad[b]==0x0D)&&(BufLoad[b+1]==0x0A)){ buferOut[c]=0; break; } buferOut[c]=BufLoad[b]; c++; } } } MessageBox(NULL,buferOut,"Размер Файла",32); ExitProcess(0); } и ещё проверку на ошибки при соединениях сам допишешь Рабочий пример скомпилированный внизу заложил Прикреплённый файлGetSizeFileServer.zip (1.23 Кбайт, скачиваний: 94) |
Сообщ.
#6
,
|
|
|
Transformer-V фига се как оперативно
Я Вам обоим очень благодарен, особенно Transformer-V Спасибо огромное!!! Даже не представляете как Вы меня выручили Пятёрка теперь обеспечена Всем по +1 П.С. а случайно аналогичного на WinAPI + WinSocks по скачке файлов нет? А то там вроде проблеммы возникают по скачке текстовых или двоичных файлов... |
Сообщ.
#7
,
|
|
|
Цитата Romeo @ Transformer-V фига се как оперативно Я Вам обоим очень благодарен, особенно Transformer-V Спасибо огромное!!! Даже не представляете как выручили Всем по +1 П.С. а случайно аналогичного на WinAPI + WinSocks по скачке файлов нет? А то там вроде проблеммы возникают по скачке текстовых или двоичных файлов... щас напишу как скачать |
Сообщ.
#8
,
|
|
|
Цитата Romeo @ Пятёрка теперь обеспечена от такого препод в обморок не упадет ?) думаю здесь лучше воспользоваться классом std::string и его методами substring и pos for (a=0;a<len;a++) { if ((BufLoad[a]=='C')&& (BufLoad[a+1]=='o')&& (BufLoad[a+2]=='n')&& (BufLoad[a+3]=='t')&& (BufLoad[a+4]=='e')&& (BufLoad[a+5]=='n')&& (BufLoad[a+6]=='t')&& (BufLoad[a+7]=='-')&& (BufLoad[a+8]=='L')&& (BufLoad[a+9]=='e')&& (BufLoad[a+10]=='n')&& (BufLoad[a+11]=='g')&& (BufLoad[a+12]=='t')&& (BufLoad[a+13]=='h')) { for (b=(a+15);b<len;b++) { if ((BufLoad[b]==0x0D)&&(BufLoad[b+1]==0x0A)){ buferOut[c]=0; break; } buferOut[c]=BufLoad[b]; c++; } } } |
Сообщ.
#9
,
|
|
|
Уфф скачал файл со своей маленькой скоростью инета 200 кбит/c 3 мегабайта с копейками своей прогой без повреждений, запускаеш прогу слышиш сигнал beep далее начинается закачка ждешь когда закачается закачалось раздался сигнал далее свое дело делает сепаратор в памяти отделяет серверную информацию от ресурса в body после этого ресурс закатывает в файл и выводит информацию о шапке и закрываеися.
Написал ... #include <windows.h> extern "C" WSADATA wsa_data; SOCKET s; sockaddr_in addr; hostent* hn; int len, szf, a, b, c, cp; char serverName[512],serverParam[512]; char serget[1280]; char BufLoad[1492]; char BuferLoadBig[10000000]; // 10 мегабайт думаю сойдет char BuferHead[1490]; char BuferSrc[10000000]; bool zatvors=false; ///3844372 HANDLE hFile; DWORD nBytesRead; void Run(); void Run() { Beep(500,100); lstrcpy(serverName,"www.kingdia.com"); lstrcpy(serverParam,"download/kingdia-video-converter.exe"); lstrcpy(serget,"GET /"); // Формирование запроса GET lstrcat(serget,serverParam); lstrcat(serget," HTTP/1.0\r\nHost: "); lstrcat(serget,serverName); lstrcat(serget,"\r\nUser-Agent: ClientDownloader\r\nAccept: text/html\r\nConnection: close\r\n\r\n"); WSAStartup(0x0202,&wsa_data); s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); hn=gethostbyname(serverName); addr.sin_family=AF_INET; addr.sin_port=htons(80); addr.sin_addr.S_un.S_addr=*(DWORD*)hn->h_addr_list[0]; connect(s,(LPSOCKADDR)&addr,sizeof(addr)); send(s,serget,lstrlen(serget),0); RtlZeroMemory(BufLoad,1492); RtlZeroMemory(BuferLoadBig,sizeof(BuferLoadBig)); do { len = recv(s,BufLoad,1492,0);; for (cp=0;cp<len;cp++) { BuferLoadBig[szf]=BufLoad[cp]; // Складываем куски байтов массив szf++; // Счетчик позиции } RtlZeroMemory(BufLoad,1492); //Чистка if (len==SOCKET_ERROR) { MessageBox(0,"Неудается принять информацию c сервера","Ошибка",MB_ICONERROR); closesocket(s); WSACleanup(); goto Error; } } while(len>0); closesocket(s); WSACleanup(); Beep(600,100); // ************ Сепаратор Шапки где-то я его на форуме выкладывал :) ************** a=0; c=0; RtlZeroMemory(BuferHead,sizeof(BuferHead)); RtlZeroMemory(BuferSrc,sizeof(BuferSrc)); for (a=0;a<szf;a++) /// Берем инфу о размере файла скаченного из сервера в szf и пихаем в цикл { if ((zatvors==false)&&(BuferLoadBig[a]==0x0d)&&(BuferLoadBig[a+1]==0x0a)&&(BuferLoadBig[a+2]==0x0d)&&(BuferLoadBig[a+3]==0x0a)) { zatvors=true; BuferHead[a]=0x00; a=a+4; } switch (zatvors) { case true: BuferSrc[c]=BuferLoadBig[a]; c++; break; case false: BuferHead[a]=BuferLoadBig[a]; break; } } BuferSrc[c]=0; // Создаем файл kingdia-video-converter.exe рядом с программа и заливаем туда все что с качале конечно BODY отсепарированное а шапка нам нафиг ненужна hFile=CreateFile("kingdia-video-converter.exe",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(hFile,&BuferSrc,c,&nBytesRead,NULL); CloseHandle(hFile); MessageBox(0,BuferHead,"Информация",32); MessageBox(0,"Файл скачан с сервера успешно ищи его рядом с программой","Информация",32); Error: ExitProcess(0); } Файл скачался благополучно ) Пример компилированный заложил вниз Прикреплённый файлDownloadFileServer.zip (1.4 Кбайт, скачиваний: 107) |
Сообщ.
#10
,
|
|
|
Цитата popsa @ Цитата Romeo @ Пятёрка теперь обеспечена от такого препод в обморок не упадет ?) думаю здесь лучше воспользоваться классом std::string и его методами substring и pos for (a=0;a<len;a++) { if ((BufLoad[a]=='C')&& (BufLoad[a+1]=='o')&& (BufLoad[a+2]=='n')&& (BufLoad[a+3]=='t')&& (BufLoad[a+4]=='e')&& (BufLoad[a+5]=='n')&& (BufLoad[a+6]=='t')&& (BufLoad[a+7]=='-')&& (BufLoad[a+8]=='L')&& (BufLoad[a+9]=='e')&& (BufLoad[a+10]=='n')&& (BufLoad[a+11]=='g')&& (BufLoad[a+12]=='t')&& (BufLoad[a+13]=='h')) { for (b=(a+15);b<len;b++) { if ((BufLoad[b]==0x0D)&&(BufLoad[b+1]==0x0A)){ buferOut[c]=0; break; } buferOut[c]=BufLoad[b]; c++; } } } Главное работает же и всё понятно!!! Ну условие немного длинновато, но если смотреть в сторону оптимизаци, то парсинг же можно всевозможными способами можно организовать... Это как один из вариантов |
Сообщ.
#11
,
|
|
|
Romeo
Если слишком длинно кажется можешь урезать .... (BufLoad[a+11]=='g')&& (BufLoad[a+12]=='t')&& (BufLoad[a+13]=='h')) .... |
Сообщ.
#12
,
|
|
|
Transformer-V
Фига се так быстро Я просто твой должник, спасибо тебе огромное |
Сообщ.
#13
,
|
|
|
Цитата Romeo @ Transformer-V Фига се так быстро Я просто твой должник, спасибо тебе огромное Незачто )) я люблю когда мне дают задачи я то сам самоучка это мое хобби )) и мне это нравится |
Сообщ.
#14
,
|
|
|
Смеёшься да меня это на все 100% устраивает!!!
|
Сообщ.
#15
,
|
|
|
Цитата Romeo @ Смеёшься да меня это на все 100% устраивает!!! Я рад |